Ответ 1
Вы можете использовать:
grep -l Dansk * | xargs grep -l Norsk | xargs grep -l Svenska
Если вы хотите также найти в скрытых файлах:
grep -l Dansk .* | xargs grep -l Norsk | xargs grep -l Svenska
Я хочу grep для файлов, содержащих слова Dansk
, Svenska
или Norsk
в любой строке, с полезным кодом возврата (поскольку мне действительно нравится только информация о том, что строки содержатся, лайнер идет немного дальше, чем это).
У меня есть много файлов с строками в них:
Disc Title: unknown
Title: 01, Length: 01:33:37.000 Chapters: 33, Cells: 31, Audio streams: 04, Subpictures: 20
Subtitle: 01, Language: ar - Arabic, Content: Undefined, Stream id: 0x20,
Subtitle: 02, Language: bg - Bulgarian, Content: Undefined, Stream id: 0x21,
Subtitle: 03, Language: cs - Czech, Content: Undefined, Stream id: 0x22,
Subtitle: 04, Language: da - Dansk, Content: Undefined, Stream id: 0x23,
Subtitle: 05, Language: de - Deutsch, Content: Undefined, Stream id: 0x24,
(...)
Вот псевдокод того, что я хочу:
for all files in directory;
if file contains "Dansk" AND "Norsk" AND "Svenska" then
then echo the filename
end
Каков наилучший способ сделать это? Можно ли это сделать на одной строке?
Вы можете использовать:
grep -l Dansk * | xargs grep -l Norsk | xargs grep -l Svenska
Если вы хотите также найти в скрытых файлах:
grep -l Dansk .* | xargs grep -l Norsk | xargs grep -l Svenska
Еще один способ, используя только bash и grep:
Для одного файла test.txt:
grep -q Dansk test.txt && grep -q Norsk test.txt && grep -l Svenska test.txt
Будет напечатан test.txt
, если файл содержит все три (в любой комбинации). Первые два greps ничего не печатают (-q
), а последнее только печатает файл, если остальные два прошли.
Если вы хотите сделать это для каждого файла в каталоге:
for f in *; do grep -q Dansk $f && grep -q Norsk $f && grep -l Svenska $f; done
Как grep для нескольких строк в файле на разных строках (используйте символ pipe):
for file in *;do
test $(grep -E 'Dansk|Norsk|Svenska' $file | wc -l) -ge 3 && echo $file
done
Примечания:
Если вы используете двойные кавычки ""
с вашим grep, вам нужно будет выйти из этого канала следующим образом: \|
для поиска Dansk, Norsk и Svenska.
Предполагается, что одна строка имеет только один язык.
Пошаговое руководство: http://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/
grep –irl word1 * | grep –il word2 `cat -` | grep –il word3 `cat -`
-i
делает регистр нечувствительным к регистру-r
делает рекурсивный поиск файлов через папки-l
показывает список файлов со словомcat -
заставляет следующий grep просматривать файлы, переданные ему в список.Вы можете сделать это очень легко с помощью ack:
ack -l 'cats' | ack -xl 'dogs'
-l
: вернуть список файлов-x
: взять файлы из STDIN (предыдущий поиск) и выполнять поиск только этих файловИ вы можете просто сохранить трубопровод, пока не получите только нужные вам файлы.
awk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print "0" }'
вы можете поймать возвращаемое значение с помощью оболочки
если у вас есть Ruby (1.9 +)
ruby -0777 -ne 'print if /Dansk/ and /Norsk/ and /Svenka/' file
Это смешение ответов glenn jackman и kurumi, которое позволяет произвольное количество регулярных выражений вместо произвольного количества фиксированных слов или фиксированного набора регулярных выражений.
#!/usr/bin/awk -f
# by Dennis Williamson - 2011-01-25
BEGIN {
for (i=ARGC-2; i>=1; i--) {
patterns[ARGV[i]] = 0;
delete ARGV[i];
}
}
{
for (p in patterns)
if ($0 ~ p)
matches[p] = 1
# print # the matching line could be printed
}
END {
for (p in patterns) {
if (matches[p] != 1)
exit 1
}
}
Запустите его следующим образом:
./multigrep.awk Dansk Norsk Svenska 'Language: .. - A.*c' dvdfile.dat
Просто:
grep 'word1\|word2\|word3' *
см. этот пост для получения дополнительной информации
Развернувшись на @kurumi awk, здесь функция bash:
all_word_search() {
gawk '
BEGIN {
for (i=ARGC-2; i>=1; i--) {
search_terms[ARGV[i]] = 0;
ARGV[i] = ARGV[i+1];
delete ARGV[i+1];
}
}
{
for (i=1;i<=NF; i++)
if ($i in search_terms)
search_terms[$1] = 1
}
END {
for (word in search_terms)
if (search_terms[word] == 0)
exit 1
}
' "[email protected]"
return $?
}
Использование:
if all_word_search Dansk Norsk Svenska filename; then
echo "all words found"
else
echo "not all words found"
fi
Вот что сработало для меня:
find . -path '*/.svn' -prune -o -type f -exec gawk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print FILENAME }' {} \;
./path/to/file1.sh
./another/path/to/file2.txt
./blah/foo.php
Если бы я просто хотел найти файлы .sh с этими тремя, я мог бы использовать:
find . -path '*/.svn' -prune -o -type f -name "*.sh" -exec gawk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print FILENAME }' {} \;
./path/to/file1.sh
Я сделал это с двумя шагами. Составить список файлов csv в одном файле С помощью этой страницы я сделал два сценария без скриптов, чтобы получить то, что мне нужно. Просто введите терминал:
$ find /csv/file/dir -name '*.csv' > csv_list.txt
$ grep -q Svenska `cat csv_list.txt` && grep -q Norsk `cat csv_list.txt` && grep -l Dansk `cat csv_list.txt`
он сделал именно то, что мне нужно - напечатать имена файлов, содержащие все три слова.
Также обратите внимание на символы типа `' "
Выполняет поиск нескольких слов в нескольких файлах:
egrep 'abc|xyz' file1 file2 ..filen
Если вам нужны только два условия поиска, возможно, наиболее читаемый подход - запустить каждый поиск и пересечь результаты:
comm -12 <(grep -rl word1 . | sort) <(grep -rl word2 . | sort)
У меня была эта проблема сегодня, и все однострочники здесь не удались, потому что в файлах содержались пробелы в именах.
Вот что я придумал:
grep -ril <WORD1> | sed 's/.*/"&"/' | xargs grep -il <WORD2>