Я хочу найти файлы, содержащие две строки вместе, например, файл содержит оба string1
и string2
.
Я хочу полный путь файлов в выводе. Я не хочу видеть предупреждения "отказано в разрешении".
grep -l string2 `grep -l string1 /path/*`
который так же, как
grep -l string2 $(grep -l string1 /path/*)
Изменить: вот почему grep string1 /path/* | grep string2
не делает то, что я думаю, alwbtc хочет.
$ cd /tmp
$ cat a
apples
oranges
bananas
$ cat b
apples
mangoes
lemons
$ cat c
mangoes
limes
pears
$ cd ~
$ grep apples /tmp/* | grep mangoes
$
Ничего не найдено, но файл b содержит обе строки.
Вот что я думаю, что alwbtc хочет
$ grep -l apples $(grep -l mangoes /tmp/*)
/tmp/b
-l
опцию для возврата имен файлов вместо строк. Затем он использует знак доллара или обратные кавычки, чтобы передать этот список в качествеFILE
аргумента во второй grep. Это позволяет второму grep выполнять поиск по всему найденному файлу, а не по отдельным строкам, как в моем решении.-l
опцию, чтобы обе команды считались равными.Труба одно
grep
в другое:grep "string1" /path/to/files/* | grep "string2"
источник
Вот эквивалент изведКоманда для ответа RedGrittyBrick :
Работает так же (за исключением того, что
ack
по умолчанию ищет текущий каталог рекурсивно). Содержимое в$()
поиске,string1
но-l
выводит только имена файлов, где была найдена эта строка. Затем они передаются в качестве аргументов во внешнюю команду, что означает, чтоstring2
поиск производится только в этом списке файлов.источник
или менее избыточно:
Это будет работать, если строки находятся в разных строках одного и того же файла, а также позволит избежать ложных срабатываний, если имя файла содержит одну из строк.
источник
Чтобы уточнить решение @ RedGrittyBrick, которое имеет недостаток при запуске команды без присмотра, плюс для подавления вывода ошибок по назначению и рекурсивного поиска файлов, вы можете рассмотреть
grep -l 'STRING1' $(! grep -lrs 'STRING2' /absolute/path/to/search/dir && echo /dev/null)
-s
опция подавляет сообщения об ошибках;-r
опция позволяет искать строки в произвольно вложенных каталогах в!
сочетании с&& echo /dev/null
гарантией того, что команда не будет зависать. В противном случае, еслиinner grep
файл не найден, он ничего не выведет, так что онouter grep
будет бесконечно ждать ввода для поиска. Это решение выводит/dev/null
в этих случаях такouter grep
будет искатьSTRING1
в/dev/null
котором он должен ничего не найти.источник
Я искал расширяемый способ сделать 2 или более строк и придумал это:
Первый grep рекурсивно находит имена файлов, содержащихся
string1
внутриpath-to-files
.Результат передается по
xargs
одной или нескольким командам grep для этих файловstring2
.Затем результаты передаются в другую
xargs
команду дляstring3
- она такая же, как первыйxargs
вызов, но ищет другую строку.Использование
xargs
позволит избежать проблем, когда результатов будет так много, что полученная командная строка от использования обратных тиков будет слишком длинной.Чтобы избежать предупреждений, мы можем перенаправить
stderr
на/dev/null
:Это не требуется при последующих вызовах grep, поскольку
string1
он уже найден внутри файла, поэтому известно, что разрешения хорошие.источник