поиск нескольких строк в нескольких файлах внутри каталога и вывод строки и соответствующего имени файла, в котором она была найдена

поиск нескольких строк в нескольких файлах внутри каталога и вывод строки и соответствующего имени файла, в котором она была найдена

У меня около 500 строк, и я хочу найти файлы, которые их содержат внутри каталога, и получить имена файлов, которые содержат строки. До сих пор я использовал:

find -name 'LYFNRE.*' -exec grep -f file1.txt {} \; -print

но проблема в том, что строка может быть найдена во многих файлах, поэтому трудно найти, какие строки присутствуют, а какие отсутствуют из-за огромного вывода. Можете ли вы помочь мне распечатать строки с соответствующими именами файлов, где они были найдены.

решение1

Вы должны просто позволить grepдать вам имена файлов. GNU grepможет сделать это:

grep -HFf ../strings.txt *

Это предоставит вам вывод, который выглядит следующим образом:

[filename]:[matched_line]

...для каждого совпадения в каждом файле в каталоге. Вы также можете получить номера строк:

grep -HnFf ../strings.txt *

...которая обеспечивает...

[filename]:[line_number]:[matched_line]

решение2

Проблема в том, что вы передаете один файл за раз в grep. Когда grepвидит один файл в своей командной строке, он предполагает, что вы точно знаете, где ищете, поэтому он не отображает имя файла перед совпадениями.

Трюк, чтобы заставить grepвсегда выводить имя файла, — это также передать /dev/null(где не будет никакого совпадения). В некоторых реализациях grep есть опция для этого: -H.

Кроме того, вы можете использовать -exec … {} +вместо -exec … {} \;для выполнения программы для многих файлов за один раз. Это быстрее. Вам все равно следует передать /dev/nullили -H, поскольку может случиться, что команда будет вызвана только для одного файла, либо потому, что есть один совпадающий файл, либо потому, что есть много совпадений, требующих , чтобы grepбыл вызван несколько раз, и один раз касается одного файла.

find -name 'LYFNRE.*' -exec grep -f file1.txt /dev/null {} +

GNU grep и последние реализации BSD (включая OSX) поддерживают опции для grepрекурсивного вызова без необходимости использования find.

grep -R --include='LYFNRE.*' -f file1.txt -H .

В качестве альтернативы вы можете сделать рекурсивную подстановку в вашей оболочке. В zsh это работает из коробки. В bash вам нужно shopt -s globstarсначала запустить, и будьте осторожны, что bash рекурсивно использует символические ссылки на каталоги (в отличие findот zsh).

grep -f file1.txt /dev/null **/LYFNRE.*

решение3

используйте egrep:

egrep -n "str1|str2|str3" file_names

-n выведет номер строки в указанном файле, где была найдена строка

Связанный контент