Я хочу найти все файлы, которые содержат определенную строку текста. grep
управляйте работами, но я не знаю, как использовать его для каждого каталога (я могу только сделать это для своего текущего каталога). Я пытался читать man grep
, но это не привело ни к какой справке.
Лучше использовать
grep -rl "string" /path
, где
-r
(или --recursive
) используется для прохождения также по всем подкаталогам /пути
, в то время как опция -l
(или -файлы с совпадающими именами
) используется только для печати имен файлов, совпадающих друг с другом, а не для печати строк с совпадающими именами (это также может повысить скорость, учитывая, что grep
прекращает чтение файла при первом совпадении с этой опцией). Обновление 2:
Эта строка команд с помощью find
и grep
исправляет проблему:
$ find path_to_search_in -type f -exec grep -in searchString {} 2> /dev/null +
--color=<всегда или автоматически>
для цветного вывода:
$ 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 +
Пример прогона в снимке, приведенном ниже:
Обновление 1:
Можно попробовать следующий код; в качестве функции в вашем .bashrc
или .bash_aliases
или в скрипте:
wherein () { для i в $(найти "$1" - тип f 2> /dev/null); делать если grep --color=auto -i "$2" "$i" 2> /dev/null; то echo -e "\033[0;32mFound in: $i \033[0m\n"; fi; готово }
Использование: wherein /path/to/search/in/ searchkeyword
example:
$ wherein ~/Documents/ "hello world"
(Примечание: Как предлагается в комментариях ниже @enzotib, это не работает с файлами/директориями, включая пробелы в их именах).
Original post
Для поиска строки и вывода только этой строки со строкой поиска:
$ 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;
Для таких нужд предназначена команда rgrep
Если она недоступна, вы можете получить ее следующим образом
mkdir -p ~/bin
cd ~/bin
wget http://sdjf.esmartdesign.com/files/rgrep
chmod +x rgrep
Вы можете напрямую установить параметры grep по умолчанию, как описано выше.
Я лично использую
[[ ${#args} -lt 5 && "${args//[[:space:]]/}" == "-i" ]] && args="-Hin"
args="${args:--Hns} --color=auto"
связанная тема: как всегда использовать rgrep с цветом
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
. Если вы ищете совпадения строк в файлах, моя любимая команда:
grep -Hrn 'search term' path/to/files
-H
вызывает печать имени файла (подразумевается при поиске нескольких файлов)-r
выполняет рекурсивный поиск-n
, в результате чего номер строки, которая должна быть напечатанаpath/to/files
может быть .
для поиска в текущем каталоге
-n может быть
-I
игнорирует двоичные файлы (дополнение: -a
рассматривают все файлы как текст)-F
рассматривают поисковый термин
как буквальный, а не как регулярное выражение-i
выполняют поиск с нечувствительностью регистра--color=всегда
, чтобы форсировать цвет даже при прохождении через -менее
. Для того, чтобы -менее
поддерживали цвета, необходимо использовать опцию -r
:
- grep -Hrn поиск . | меньше -r
--exclude-dir=dir
полезно для исключения каталогов типа .svn
и .git
.Моя команда по умолчанию -
grep -Rin string *
Я использую капитолий 'R', потому что ls
использует его для рекурсивных целей. Так как grep принимает оба, нет причин не использовать его.
EDIT: в HVNSweeting, очевидно -R
будет следовать за симлинками, где как -r
не будет.
Полагаю, вы можете использовать нечто подобное:
find /path -type f -exec grep -l "string" {} \;
Пояснения из комментариев
find
- это команда, которая позволяет найти файлы и другие объекты, такие как каталоги и ссылки в подкаталогах заданного пути. Если вы не укажете маску, которой должны соответствовать имена файлов, она перечислит все объекты каталогов.
-тип f
указывает, что она должна обрабатывать только файлы, а не каталоги и т.д. -exec grep
указывает, что для каждого найденного файла он должен выполнить команду grep, передавая ему в качестве аргумента свое имя файла, заменив {}
именем Если вы хотите попробовать что-то новое, сделайте снимок ack
-. Команда для рекурсивного поиска текущей директории по строке
такая:
ack string
Установка довольно проста:
curl http://betterthangrep.com/ack-standalone > ~/bin/ack && chmod 0755 !#:3
(При условии, что у Вас уже есть каталог ~/bin
и он предпочтительно в Вашем PATH
. )
Я делаю это с помощью 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.
Сценарий (код поиска) для поиска в C, код CPP:
#!/bin/sh
find . \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" \) -type f -print0 | xargs -0 grep --color -n "$1"
Используйте:
find-in-code "search string"
Существует очень быстрая альтернатива grep, называемая Platinum Searcher. Вы можете скачать его здесь .