Поиск файлов, которые содержат определенную строку, используя find (1) и grep (1)

70

find . -type f -print -exec cat {} \; | grep some string

Команда выше не печатает путь к файлу.

Я использую: Ubuntu, bash 4.

H.Rabiee
источник
Возможно, это не соответствует ожидаемым результатам из-за фильтра grep. Как насчет этого:find . -type f -fprint /dev/stderr -exec cat {} \; | grep some string
artistoex
Какую цель вы хотите достичь? На выходе вы получаете grep строки из файлов, вы хотите путь этих файлов?
Миркобранкович
Да, я хочу напечатать путь к файлам, которые содержат строку «некоторая строка». Предложение @artistoex выводит все пути к файлам.
Х.Раби
Вы можете просто захотеть использовать ackgrep для просмотра всех файлов в текущем каталоге, возможно, фильтруя только определенные типы файлов.
Яап Старейшина

Ответы:

87

Это потому, что вы передаете grepпоток текста, который просто содержит имена файлов. Так как вы не указали имена файлов в качестве аргументов для grep, нельзя ожидать, что из этого файла будет получена совпадающая строка. Используйте xargs:

find . -type f -print | xargs grep "some string"

Поскольку у вас есть GNU find / xargs, для xargs это более безопасный способ чтения имен файлов:

find . -type f -print0 | xargs -0 grep "some string"

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

find . -type f -print0 | xargs -0 grep -l "some string"
Гленн Джекман
источник
Как бы я сочетал вышеуказанные команды с поиском и заменой? Как в grep то седь?
CMCDragonkai
1
конвейер find | grep выводит имена файлов, поэтому:sed '...' $(find ... | xargs grep -l ...)
glenn jackman
107

я использую

grep "some string" . -R

и это работает быстрее

п.с.

Более сложный вариант использования

grep -HiRE "some string|other string" . #H for file printing, i for case-insensitive, R for recursive search, E for regex 

Читать параграф и объяснение

grep --help | grep -- -i
ArcherGodson
источник
17
И -nесли вы хотите номера строк. +1 за упрощенный ответ.
Чад Скитерс
@ChadSkeeters точно. Использование находки не дает такого решения.
ArcherGodson
1
Это должно быть помечено как правильный ответ, если честно. Выбранный в данный момент один детализирует что-то еще полностью.
12

Я часто ищу исходный код в сложных структурах папок и считаю полезным использование:

cd /your/folder/
grep -rHino "your string"

С этими параметрами, не используя find , я получаю полный путь к файлу и номер строки, которая содержит указанную строку .

Это также легко запомнить, потому что это BASH проходит через ваш поиск как носорог :)

Я покажу, как это работает, на быстром примере.

Давайте отобразим содержимое файла, используя cat:

jeeves ~ # cat fw.stop
#!/bin/sh
echo "Stopping firewall and allowing everyone..."
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

И давайте рекурсивно ищем все файлы, содержащие строку «iptables -P»:

jeeves ~ # grep -rinHo "iptables -P"
fw.stop:9:iptables -P
fw.stop:10:iptables -P
fw.stop:11:iptables -P

Как вы можете видеть в выводе, у нас есть имя файла: строка попаданий: искомая строка

Вот более подробное описание используемых параметров:

-r Для каждого операнда каталога рекурсивно читать и обрабатывать все файлы в этом каталоге. Перейдите по символическим ссылкам в командной строке, но пропустите символические ссылки, которые встречаются рекурсивно. Обратите внимание, что если файловый операнд не задан, grep ищет рабочий каталог. Это то же самое, что и опция --directories = recurse.

-i Распечатать имя файла для каждого совпадения. Это значение по умолчанию, когда для поиска требуется более одного файла.

-n Префикс каждой строки вывода с номером строки на основе 1 в своем входном файле. (-n определяется POSIX.)

-H Распечатать имя файла для каждого совпадения. Это значение по умолчанию, когда для поиска требуется более одного файла.

-o Печать только совпадающих (непустых) частей совпадающих строк, каждая из которых находится на отдельной выходной строке. В выходных строках используются те же разделители, что и для ввода, а разделители являются нулевыми байтами, если также используется -z (--null-data) (см. Другие параметры).

Pitto
источник
2

я предпочел

| найти файл | make grep ont find file | показать полный путь к файлу

find / -type f -exec grep 'some string' {} \; -exec echo {} \;

user515185
источник
0

Silver Searcher - это очень быстрый и удобный инструмент для поиска файлов и контента.

Чтобы решить вашу проблему, команда поиска серебра должна выглядеть следующим образом ...

ag 'some string' -l

-l Печатать только имена файлов, содержащие совпадения (не печатать совпадающие строки)

qoomon
источник