Как использовать команду "grep" для поиска текста, включая подкаталоги

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

Было бы лучше использовать

grep -rl "string" /path

где

  • -r (или --recursive) опция используется также для обхода всех подкаталогов /path, в то время как
  • -l (или --files-with-matches) опция используется только для печати имен файлов соответствующих файлов, а не совпадающих строк (это также может повысить скорость, учитывая, что grep остановить чтение файла при первом совпадении с этой опцией).

Если вы ищете совпадение строк в файлах, моя любимая команда -:

grep -Hrn 'search term' path/to/files
  • -H вызывает печать имени файла (подразумевается при поиске по нескольким файлам)
  • -r выполняет рекурсивный поиск
  • -n вызывает печать номера строки

path/to/files может быть . для поиска в текущем каталоге

Дополнительные варианты, которые я нахожу очень полезными:

  • -I игнорировать двоичные файлы (дополнение: -a обрабатывать все файлы как текст)
  • -F лечить search term как литерал, а не как регулярное выражение
  • -i выполните поиск без учета регистра
  • --color=always для усиления цвета даже при прохождении трубопровода через less. Чтобы сделать less цвета поддержки, вам необходимо использовать -r вариант:

    grep -Hrn search . | less -r
  • --exclude-dir=dir полезно для исключения таких каталогов, как .svn и .git.

Example output

Я полагаю, вы можете использовать что-то вроде этого:

find /path -type f -exec grep -l "string" {} \;

Объяснение из комментариев

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

  • -type f указывает, что он должен обрабатывать только файлы, а не каталоги и т.д.
  • -exec grep указывает, что для каждого найденного файла он должен запускать команду grep, передавая ей имя файла в качестве аргумента, заменяя {} с именем файла

Моя команда по умолчанию такова

grep -Rin string *

Я использую заглавную букву "Р", потому что ls использует его для рекурсивного. Поскольку grep принимает и то, и другое, нет причин не использовать его.

РЕДАКТИРОВАТЬ: по-видимому, за HVNSweeting -R будет следовать символическим ссылкам, где как -r не будет.

Если вы готовы попробовать что-то новое, дайте ack выстрел. Команда для рекурсивного поиска в текущем каталоге для string является:

ack string

Установка довольно проста:

curl http://betterthangrep.com/ack-standalone > ~/bin/ack && chmod 0755 !#:3

(При условии, что у вас уже есть каталог ~/bin и желательно, чтобы это было в вашем PATH.)

Команда rgrep предназначена для такой необходимости

Если он недоступен, вы можете получить его следующим образом

mkdir -p ~/bincd ~/binwget http://sdjf.esmartdesign.com/files/rgrepchmod +x rgrep

Вы можете напрямую установить параметры grep по умолчанию, как описано выше.

Я лично использую

[[  ${#args} -lt 5 && "${args//[[:space:]]/}" == "-i" ]] && args="-Hin"args="${args:--Hns} --color=auto"

смежная тема : как всегда использовать rgrep с цветом

Обновление 2:

Эта строка команд, использующая find и grep устраняет проблему:

$ find path_to_search_in -type f -exec grep -in searchString {} 2> /dev/null +

--color=<always or auto> для цветного вывода:

$ find path_to_search_in -type f \            -exec grep --color=always -in searchString {} 2>/dev/null +

Пример:

$ find /tmp/test/ -type f -exec grep --color=auto -in "Search string" {} 2>/dev/null +

Пример выполнения на снимке ниже:snap1


Обновление 1:

Вы можете попробовать следующий код; как функция в вашем .bashrc или .bash_aliases или в сценарии:

wherein () {     for i in $(find "$1" -type f 2> /dev/null);    do        if grep --color=auto -i "$2" "$i" 2> /dev/null; then            echo -e "\033[0;32mFound in: $i \033[0m\n";        fi;    done}

Использование: wherein /path/to/search/in/ searchkeyword

пример:

$ wherein ~/Documents/ "hello world"

(Примечание: Как было предложено в комментариях ниже @enzotib, это не работает с файлами / каталогами, включающими пробелы в их именах.)


Оригинальное сообщение

Для поиска строки и вывода только этой строки со строкой поиска:

$ for i in $(find /path/of/target/directory -type f); do \    grep -i "the string to look for" "$i"; done

напр.:

$ for i in $(find /usr/share/applications -type f); \    do grep -i "web browser" "$i"; done

Для отображения имени файла, содержащего строку поиска:

$ for i in $(find /path/of/target/directory -type f); do \    if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

напр.:

$ for i in $(find /usr/share/applications -type f); \    do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \    fi; done;

grep (GNU или BSD)

Вы можете использовать grep инструмент для рекурсивного поиска текущей папки с -r параметр, подобный:

grep -r "pattern" .

Примечание: -r - Рекурсивный поиск в подкаталогах.

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

grep "class foo" **/*.c

Примечание: С помощью опция глобулирования (**), он рекурсивно сканирует все файлы с определенным расширением или шаблоном. Чтобы включить этот синтаксис, запустите: shopt -s globstar. Вы также можете использовать **/*.* для всех файлов (за исключением скрытых и без расширения) или любого другого шаблона.

Если у вас есть ошибка, заключающаяся в том, что ваш аргумент слишком длинный, подумайте о том, чтобы сузить поиск или использовать find синтаксис вместо этого, такой как:

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

В качестве альтернативы используйте ripgrep.

ripgrep

Если вы работаете над большими проектами или большими файлами, вам следует использовать ripgrep вместо этого, как:

rg "pattern" .

Ознакомьтесь с документами, шагами установки или исходным кодом на Страница проекта GitHub.

Это намного быстрее, чем любой другой инструмент, такой как GNU/BSD grep, ucg, ag, sift, ack, pt или аналогичный, поскольку он построен поверх Механизм регулярных выражений Rust который использует конечные автоматы, SIMD и агрессивную оптимизацию букв, чтобы сделать поиск очень быстрым.

Он поддерживает шаблоны игнорирования, указанные в .gitignore файлы, так что один путь к файлу может быть сопоставлен с несколькими глобальными шаблонами одновременно.


Вы можете использовать общие параметры, такие как:

  • -i - Нечувствительный поиск.
  • -I - Игнорируйте двоичные файлы.
  • -w - Поиск целых слов (в отличие от частичного сопоставления слов).
  • -n - Покажите линию вашего матча.
  • -C/--context (например -C5) - Увеличивает контекст, так что вы видите окружающий код .
  • --color=auto - Отметьте соответствующий текст.
  • -H - Отображает имя файла, в котором находится текст.
  • -c - Отображает количество совпадающих строк. Может сочетаться с -H.

Я делаю это с помощью xargs, очень недооцененной команды

find ./ -type f -print0 | xargs -0 grep 'string_you_are_looking_for'

find ./ дает вам рекурсивный список всех файлов в текущей папке, затем вы передаете его в xargs, который выполняет команду grep для каждого из этих файлов

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

find . -type f -exec grep --quiet string_to_look_for {} ';' -print

Это работает, потому что grep вернет 0, если он нашел результат, 1 в противном случае. Например, вы можете найти файлы размером 1 МБ и содержащий что-то:

find . -type f -exec grep --quiet string_to_look_for {} ';' -size 1M -print

Для нескольких требований вы, вероятно, захотите использовать флаг оптимизатора -O это существует в GNU grep.

Подстановочный знак с опцией `–include="*.C"’, @user311346, спасибо @Lekensteyn.

Используйте комбинацию find и grep для рекурсивного поиска файлов по строке в текущем и во всех подкаталогах. Проверьте это http://wilddiary.com/find-files-containing-my-text/

grep -RIn <ваш шаблон> * Будет выполнять поиск по текущим каталогам во всех текстовых файлах.
Не уверен, как выполнить рекурсивный поиск в шаблонах файлов, таких как *.C, используя только grep