Как сделать grep рекурсивно?
Как мне рекурсивно grep
все каталоги и подкаталоги?
find . | xargs grep "texthere" *
24 ответов
grep -r "texthere" .
первый параметр представляет регулярное выражение для поиска, в то время как второй представляет собой каталог, который следует искать. В этом случае .
означает текущий каталог.
Примечание: это работает для GNU grep, и на некоторых платформах, таких как Solaris, вы должны специально использовать GNU grep в отличие от устаревшей реализации. Для Solaris это .
если вы знаете расширение или шаблон файла, который вы хотите, другой метод-использовать :
grep -r --include "*.txt" texthere .
вы также можете упомянуть файлы для исключения с помощью --exclude
.
Ag
если вы часто поиск через код Ag (Серебряный Искатель) является гораздо более быстрой альтернативой grep, которая настроена для поиска кода. Например, он рекурсивен по умолчанию и автоматически игнорирует файлы и каталоги, перечисленные в .gitignore
, поэтому вам не нужно продолжать передавать те же громоздкие опции исключения grep или find.
я теперь всегда использую (даже на Windows с GoW -- Gnu на Windows):
grep --include="*.xxx" -nRHI "my Text to grep" *
это включает в себя следующие параметры:
--include=PATTERN
рекурсия в каталогах только поиск файлов, которые соответствуют
PATTERN
.
-n, --line-number
префикс каждой строки вывода с номером строки в его входном файле.
-R, -r, --recursive
читать все файлы в каждом каталоге рекурсивно; это эквивалент .
-H, --with-filename
печать имени файла для каждого матча.
-I
обработайте двоичный файл так, как будто он не содержит совпадающих данных;
это эквивалентно .
и я могу добавить 'i
' (-nRHIi
), если мне нужны результаты без учета регистра.
я могу сделать:
/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43: 'git.hidden' => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21: $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32: $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20: protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170: * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176: return $this->hidden;
...
в системах POSIX вы не найдете на grep
и свой grep -rn "stuff" .
не будет работать, но если вы используете это:
find . -type f -exec grep -n "stuff" {} \; -print
согласовано Solaris
и HP-UX
.
найти имя files
С path
рекурсивно, содержащий в частности string
используйте команду ниже
для UNIX
:
find . | xargs grep "searched-string"
на Linux
:
grep -r "searched-string" .
находим файл UNIX
сервер
find . -type f -name file_name
найти файл на сервере LINUX
find . -name file_name
ag-мой любимый способ сделать это сейчас github.com/ggreer/the_silver_searcher . Это в основном то же самое, что и ack, но с несколькими оптимизациями.
вот короткий тест. Я очищаю кэш перед каждым тестом (cf https://askubuntu.com/questions/155768/how-do-i-clean-or-disable-the-memory-cache)
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .
real 0m9.458s
user 0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .
real 0m6.296s
user 0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .
real 0m5.641s
user 0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache
real 0m0.154s
user 0m0.224s
sys 0m0.172s
если вы хотите только следовать фактическим каталогам, а не символическим ссылкам,
grep -r "thingToBeFound" directory
если вы хотите следовать символическим ссылкам, а также фактическим каталогам (будьте осторожны с бесконечной рекурсией),
grep -R "thing to be found" directory
так как вы пытаетесь grep рекурсивно, следующие параметры также могут быть полезны для вас:
-H: outputs the filename with the line
-n: outputs the line number in the file
поэтому, если вы хотите найти все файлы, содержащие Darth Vader в текущем каталоге или любых подкаталогах, и захватить имя файла и строку номер, но не хотите, чтобы рекурсия следовала символическим ссылкам, команда будет
grep -rnH "Darth Vader" .
если вы хотите найти все упоминания о слове кошка в директории
/home/adam/Desktop/TomAndJerry
и вы в настоящее время в каталоге
/home/adam/Desktop/WorldDominationPlot
и вы хотите захватить имя файла, но не номер строки любого экземпляра строки "кошки", и вы хотите, чтобы рекурсия следовала символическим ссылкам, если она их найдет, вы можете запустить любой из после
grep -RH "cats" ../TomAndJerry #relative directory
grep -RH "cats" /home/adam/Desktop/TomAndJerry #absolute directory
источник:
запуск "grep -- help"
краткое введение в символические ссылки, для тех, кто читает этот ответ и смущает мое обращение к ним: https://www.nixtutor.com/freebsd/understanding-symbolic-links/
подстановка **
используя grep -r
работает, но это может перебор, особенно в больших папках.
для более практического использования, вот синтаксис, который использует подстановка синтаксис (**
):
grep "texthere" **/*.txt
который greps только определенные файлы с шаблоном выбранного шаблона. Он работает для поддерживаемых оболочек, таких как Баш +4 или ЗШ.
чтобы активировать эту функцию, выполните: shopt -s globstar
.
Читайте также: как найти все файлы, содержащие определенный текст в Linux?
git grep
для проектов под управлением версий Git используйте:
git grep "pattern"
что намного быстрее.
ripgrep
для больших проектов самый быстрый инструмент для захвата -ripgrep
какие файлы greps рекурсивно по умолчанию:
rg "pattern" .
это построен на вершине двигатель regex ржавчины который использует конечные автоматы, SIMD и агрессивные буквальные оптимизации, чтобы сделать поиск очень быстрым. Проверьте подробный анализ здесь.
если вы ищете определенный контент во всех файлах из структуры каталогов, вы можете использовать find
так как более ясно, что вы делаете:
find -type f -exec grep -l "texthere" {} +
отметим, что -l
(downcase of L) показывает имя файла, содержащего текст. Удалите его, если вы хотите напечатать само совпадение. Или использовать -H
собрать файл с матчем. Все вместе, другие альтернативы:
find -type f -exec grep -Hn "texthere" {} +
здесь -n
печать номера строки.
Это тот, который работал для моего случая на моей текущей машине (Git bash на windows 7):
find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"
Я всегда забываю-print0 и -0 для путей с пробелами.
EDIT: мой предпочтительный инструмент теперь вместо ripgrep:https://github.com/BurntSushi/ripgrep/releases . Это очень быстро и имеет лучшие значения по умолчанию (например, рекурсивные по умолчанию). Же пример, как мой оригинальный ответ, но используя ripgrep: rg -g "*.cs" "content pattern"
в моем сервере IBM AIX (версия ОС: AIX 5.2) используйте:
find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \;
это выведет путь/имя файла и относительный номер строки в файле, как:
./ inc / xxxx_x.h
2865: / * * описание: stringYouWannaFind*/
в любом случае,это работает для меня : )
grep -r "texthere" .
(период уведомления в конце)
(^кредит:https://stackoverflow.com/a/1987928/1438029)
пояснение:
grep -r "texthere" /
(рекурсивно grep все каталоги и подкаталоги)
grep -r "texthere" .
(рекурсивно grep эти каталоги и подкаталоги)
рекурсивный grep
grep [options] PATTERN [FILE...]
[параметры]
-R, -r, --recursive
читать все файлы в каталог, рекурсивно.
эквивалентно
-d recurse
или .
grep help
$ grep --help
$ grep --help |grep recursive
-r, --recursive like --directories=recurse
-R, --dereference-recursive
варианты
ack
(http://beyondgrep.com/)
Ниже приведены команды для поиска String
рекурсивно on Unix
и Linux
окружающая среда.
на - это:
grep -r "string to be searched" .
Я думаю, это то, что вы пытаетесь написать
grep myText $(find .)
и это может быть что-то еще полезно, если вы хотите найти файлы grep hit
grep myText $(find .) | cut -d : -f 1 | sort | uniq
в 2018 году вы хотите использовать ripgrep
или the-silver-searcher
потому что они намного быстрее, чем альтернативы.
вот каталог с 336 подкаталогами первого уровня:
% find . -maxdepth 1 -type d | wc -l
336
% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py' 1.24s user 2.23s system 283% cpu 1.222 total
% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$' 2.71s user 1.55s system 116% cpu 3.651 total
% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py' 1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs 6.65s user 0.49s system 32% cpu 22.164 total
на OSX, это устанавливает ripgrep
: brew install ripgrep
. Это устанавливает silver-searcher
: brew install the_silver_searcher
.
отметим, что find . -type f | xargs grep whatever
виды решений будут запускаться в" список аргументов для длинных " ошибок, когда есть слишком много файлов, сопоставленных find.
лучшая ставка -grep -r
но если это недоступно, используйте find . -type f -exec grep -H whatever {} \;
вместо.
просто для удовольствия, быстрый и грязный поиск *.txt-файлы, если ответ @christangrant слишком велик для ввода : -)
grep -r texthere .|grep .txt
для списка доступных флагов:
grep --help
возвращает все совпадения для regexp texthere в текущем каталоге, с соответствующим номером строки:
grep -rn "texthere" .
возвращает все матчи за texthere, начиная с корневого каталога, с соответствующим номером строки и игнорируя регистр:
grep -rni "texthere" /
флаги, используемые здесь:
-
-r
рекурсивные -
-n
номер строки печати с выходом -
-i
игнорировать делу
вот рекурсивная (слегка проверенная с помощью bash и sh) функция, которая пересекает все подпапки данной папки ($1) и использует grep
поиск заданной строки ($3) в заданных файлах ($2):
$ cat script.sh
#!/bin/sh
cd ""
loop () {
for i in *
do
if [ -d "$i" ]
then
# echo entering "$i"
cd "$i"
loop "" ""
fi
done
if [ -f "" ]
then
grep -l "" "$PWD/"
fi
cd ..
}
loop "" ""
запуск и вывод примера:
$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename