Рекурсивное использование find и возврат только совпадающих имен файлов

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

Я использую:

find . -name '*.php' -exec grep -i 'MATCH' {} \; -print

Это покажет мне каждый экземпляр MATCH, а затем имя файла, затем следующий пакет и имя файла, например:

MATCH
MATCH
MATCH
./filename
MATCH
MATCH
MATCH
./filename2

Я попытался изменить GREP на:

find . -name '*.php' -exec grep -H -i 'MATCH' {} \; -print

и это дало мне:

./filename: MATCH
./filename: MATCH
./filename: MATCH
./filename2: MATCH
./filename2: MATCH
./filename2: MATCH

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

Я попытался изменить GREP на:

find . -name '*.php' -exec grep -l -i 'MATCH' {} \; -print

и это дало мне:

./filename
./filename
./filename
./filename2
./filename2
./filename2

В идеале хотелось бы что-то вроде:

./filename
./filename2

который перечисляет только каждый файл, который соответствует один раз, независимо от того, сколько раз он встречается в каждом файле - можно ли это сделать?

1
0
308
2

Ответы 2

Используйте функции, предоставляемые grep:

-l, --files-with-matches print only names of FILEs containing matches
-R, -r, --recursive equivalent to --directories=recurse
--include=FILE_PATTERN search only files that match FILE_PATTERN
-i, --ignore-case ignore case distinctions

Т.е.

grep -ril --include="*.php" 'MATCH' .

Проблема не в grep, а в рассказыватьfind, чтобы печатать каждое имя файла:

find . -name '*.php' -exec grep -l -i 'MATCH' {} \; -print

Обратите внимание на -print в конце. Просто удалите это:

find . -name '*.php' -exec grep -l -i 'MATCH' {} \;

Посмотрите:

$ echo 'foo' > file1

$ echo 'foo' > file2

$ find . -name 'file*' -exec grep -l -i foo {} \; -print
./file1
./file1
./file2
./file2

$ find . -name 'file*' -exec grep -l -i foo {} \;
./file1
./file2

Другие вопросы по теме