Я хочу найти все файлы, которые содержат определенную строку текста. То 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
.
Я полагаю, вы можете использовать что-то вроде этого:
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 +
Пример выполнения на снимке ниже:
Обновление 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