Как я могу grep рекурсивно?

1387

Как я рекурсивно grep все каталоги и подкаталоги?

find . | xargs grep "texthere" *
  • 94
    @ TC1 Печально то, что сам grep может ответить на вопрос (по крайней мере, GNU grep): grep --help | grep recursive
  • 7
    Если вы часто используете grep для рекурсивного поиска (особенно если вы вручную выполняете много исключений файлов / каталогов), вы можете найти ack (очень удобная для программиста альтернатива grep) полезной.
Показать ещё 5 комментариев
Теги:
grep

24 ответа

2199
Лучший ответ
grep -r "texthere" .

Первый параметр представляет собой регулярное выражение для поиска, а второе представляет собой каталог, который нужно искать. В этом случае . означает текущий каталог.

Примечание. Это работает для GNU grep, и на некоторых платформах, таких как Solaris, вы должны специально использовать GNU grep в отличие от старой реализации. Для Solaris это команда ggrep.

  • 35
    Примечание: «grep -r» работает только на новых greps. Он не работает на grep, который входит в AIX 5.3 например.
  • 88
    Используйте grep -R, чтобы следовать символическим ссылкам.
Показать ещё 7 комментариев
632

Если вам известно расширение или шаблон файла, который вам нужен, другой метод заключается в использовании опции --include:

grep -r --include "*.txt" texthere .

Вы также можете указать файлы для исключения с помощью --exclude.

Ag

Если вы часто просматриваете код, Ag (The Silver Searcher) является гораздо более быстрой альтернативой grep, настроенной для поиска кода. Например, он рекурсивный по умолчанию и автоматически игнорирует файлы и каталоги, перечисленные в .gitignore, поэтому вам не нужно передавать те же громоздкие опции исключения в grep или find.

  • 3
    Прекрасно работает с grep, который поставляется с Linux и Cygwin, но не с тем, что поставляется с AIX.
  • 1
    @KrzysztofWolny: `` вместо = отлично работает в Ubuntu. PS: это должно быть пробел, но анализатор уценки SO не удался.
Показать ещё 4 комментария
113

Также:

find ./ -type f -print0 | xargs -0 grep "foo"

но grep -r - лучший ответ.

  • 43
    +1, так как это работает на HP-UX, где "grep -r" нет. Благодарю.
  • 12
    Или, если вы не хотите беспокоиться о пробелах в именах файлов, find . -type f -exec grep "foo" '{}' \; хорошо работает там, где поддерживается.
Показать ещё 8 комментариев
88

Я сейчас всегда использую (даже на Windows с GoW - Gnu на Windows):

grep --include="*.xxx" -nRHI "my Text to grep" *

Это включает в себя следующие параметры:

--include=PATTERN

Рекурсировать в каталогах только поиск файла, соответствующего PATTERN.

-n, --line-number

Префикс каждой строки вывода с номером строки в своем входном файле.

(Примечание: phuclv добавляет в комментариях, что -n снижает производительность, поэтому вы можете пропустить эту опцию)

-R, -r, --recursive

Читать все файлы в каждом каталоге, рекурсивно; это эквивалентно опции -d recurse.

-H, --with-filename

Напечатайте имя файла для каждого соответствия.

-I     

Обрабатывать двоичный файл так, как будто он не содержит совпадающих данных;
это эквивалентно параметру --binary-files=without-match.

И я могу добавить ' i ' (-nRHIi), если хочу получить результаты -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;
...
  • 3
    Ответ, который я пришел сюда, не ожидая найти. +1
  • 0
    Gow выглядит многообещающе - новее, чем утилиты GNU Windows, которые я использовал. Пытаюсь сейчас ...
Показать ещё 6 комментариев
53

Или установите ack, если вы хотите гораздо более быстрый способ и делаете это много.

22

В системах POSIX вы не найдете параметр -r для grep, а ваш grep -rn "stuff" . не будет запущен, но если вы используете команду find, он будет:

find . -type f -exec grep -n "stuff" {} \; -print

Согласовано Solaris и HP-UX.

  • 0
    Каково значение {} \; -принт соответственно?
  • 2
    В опции -exec - символ {} - это ссылка на имя файла, которое в настоящее время найдено инструментом find (то есть что-то сделать с найденным нами именем файла), также опция -exec должна заканчиваться ; символ (для обозначения окончания команд exec), но поскольку все это выполняется в оболочке, этот символ следует экранировать ... и, наконец, опция -print позволяет find инструмент для вывода найденных имен файлов на экран.
14

глотание **

Использование grep -r работает, но оно может переполняться, особенно в больших папках.

Для более практического использования здесь приведен синтаксис, который использует синтаксис globbing (**):

grep "texthere" **/*.txt

который объединяет только определенные файлы с шаблоном, выбранным шаблоном. Он работает для поддерживаемых оболочек, таких как Bash +4 или zsh.

Чтобы активировать эту функцию, запустите: shopt -s globstar.

См. Также: Как найти все файлы, содержащие определенный текст в Linux?

git grep

Для проектов под контролем версии Git используйте:

git grep "pattern"

что намного быстрее.

ripgrep

Для более крупных проектов самым быстрым инструментом ripgrep является ripgrep который по умолчанию реплицирует файлы greps:

rg "pattern" .

Он построен на основе двигателя регулярного выражения Rust, который использует конечные автоматы, SIMD и агрессивные литературные оптимизации для быстрого поиска. Проверьте подробный анализ здесь.

  • 3
    Спасибо за предложение git grep - это очень полезно, и я не знал об этом!
  • 1
    Спасибо за предложение ripgrep. Это намного быстрее.
11

Чтобы найти имя 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
10

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

grep -r -l "foo" .
8

Если вы хотите следовать только фактическим каталогам, а не символическим ссылкам,

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" .

Если вы хотите найти все упоминания слова cat в каталоге

/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/

8

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
6

Это тот, который работал для моего случая на моей текущей машине (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"

6

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

find -type f -exec grep -l "texthere" {} +

Обратите внимание, что -l (нижний регистр L) показывает имя файла, содержащего текст. Удалите его, если вы хотите распечатать сам матч. Или используйте -H, чтобы получить файл вместе с совпадением. Все вместе, другие альтернативы:

find -type f -exec grep -Hn "texthere" {} +

Где -n печатает номер строки.

  • 2
    Проголосовал за то, что это единственное решение для find позволяющее избежать ненужного использования xargs и использовать + вместо \; с -exec , тем самым избегая тонн ненужных запусков процессов. :-)
5

Это должно работать:

grep -R "texthere" *
4

grep -r "texthere" . (период уведомления в конце)

(^ кредит: https://stackoverflow.com/questions/1987926/how-do-i-grep-recursively)


Разъяснение:

grep -r "texthere" / (рекурсивно grep все каталоги и подкаталоги)

grep -r "texthere" . (рекурсивно grep эти каталоги и подкаталоги)

grep рекурсивный

grep [options] PATTERN [FILE...]

[опция]

-R, -r, --recursive

Прочитайте все файлы в каждом каталоге, рекурсивно.

Это эквивалентно опции -d recurse или --directories=recurse.

http://linuxcommand.org/man_pages/grep1.html

grep help

$ grep --help

$ grep --help |grep recursive
  -r, --recursive           like --directories=recurse
  -R, --dereference-recursive

Альтернативы

ack (http://beyondgrep.com/)

ag (http://github.com/ggreer/the_silver_searcher)

3

Ниже приведена команда поиска в String рекурсивно в среде Unix и Linux.

для команды Unix:

find . -name "string to be searched" -exec grep "text" "{}" \;

для команды Linux:

grep -r "string to be searched" .
3

В моем сервере IBM AIX (версия ОС: AIX 5.2) используйте:

find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \; 

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

./вкл/xxxx_x.h

2865:/** Описание: stringYouWannaFind */

в любом случае, он работает для меня:)

2

В 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.

  • 0
    Скорость важна, если вам нужно делать это часто, но большинство из нас делают это только несколько раз в год. Установка новейшего стороннего инструмента juju du du jour является излишним, и решения, которые не сильно изменились с 1978 года, хорошо знать независимо от них.
  • 0
    Я считаю крайне неправдоподобным, что программист будет искать текст в дереве исходного кода только несколько раз в год. Но даже с точки зрения удобства использования, rg обладает значительным преимуществом по сравнению со сборкой рекурсивной команды grep с нуля. Используя rg : rg foo . Использование инструментов Unix: find . | xargs grep foo . И если в любом из ваших файлов есть цитата, вам нужно использовать find . -print0 | xargs -0 grep foo . Собираетесь ли вы помнить это, если вы используете это несколько раз в год?
Показать ещё 1 комментарий
2

Я думаю, это то, что вы пытаетесь написать

grep myText $(find .)

и это может быть что-то еще полезно, если вы хотите найти файлы grep hit

grep myText $(find .) | cut -d : -f 1 | sort | uniq
  • 0
    Это очень интуитивно понятно: например: grep -i acc $ (найти. -Name "выполнение *. *")
1

Список доступных флагов:

grep --help 

Возвращает все совпадения для текстового выражения regexp в текущем каталоге с соответствующим номером строки:

grep -rn "texthere" .

Возвращает все совпадения для texthere, начиная с корневого каталога, с соответствующим номером строки и игнорируя случай:

grep -rni "texthere" /

флаги, используемые здесь:

  • -r рекурсивный
  • -n номер строки печати с выходом
  • -i игнорировать регистр
1

Просто для удовольствия, быстрый и грязный поиск *.txt файлов, если ответ @christangrant слишком много, чтобы напечатать: -)

grep -r texthere .|grep .txt

1

Обратите внимание, что find . -type f | xargs grep whatever варианты решений будут запущены в "Аргументный список к длинным" ошибкам, когда слишком много файлов совпадают с поиском.

Лучшая ставка - grep -r, но если это невозможно, используйте find . -type f -exec grep -H whatever {} \;.

  • 0
    А? xargs - это обходной путь для проблемы «Список аргументов слишком длинный».
  • 2
    Ну, нет - xargs специально предназначен для преобразования потока аргументов в список аргументов, но да, это правда, что современные xargs при использовании с -s и / или -L могут иметь дело с очень длинными аргументами, разбивая их на несколько вызовов команд, но он не настроен таким образом по умолчанию (и не был ни в одном из приведенных выше ответов). Как пример: find . -type f | xargs -L 100 grep whatever
Показать ещё 2 комментария
0

Здесь рекурсивный (проверенный легко с функцией bash и sh), который перемещает все подпапки заданной папки ($ 1) и использует grep выполняет поиск заданной строки ($ 3) в заданных файлах ($ 2):

$ cat script.sh
#!/bin/sh

cd "$1"

loop () {
    for i in *
    do
        if [ -d "$i" ]
        then
            # echo entering "$i"
            cd "$i"
            loop "$1" "$2"
        fi
    done

    if [ -f "$1" ]
    then
        grep -l "$2" "$PWD/$1"
    fi

    cd ..
}

loop "$2" "$3"

Запуск и вывод примера:

$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename
-3
The syntax is:
cd /path/to/dir
grep -r <"serch_word name"> .
  • 7
    Это не добавляет много к другим ответам

Ещё вопросы

Сообщество Overcoder
Наверх
Меню