Поиск файлов по контенту [dубликат]

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

297
задан Firefeather 1 August 2011 в 18:24
поделиться

99 ответов

Лучше использовать

grep -rl "string" /path

, где опция

-r (или --recursive) используется для перемещения также всех подкаталогов /path , в то время как опция -l (или --files-with-matches) используется для печати только файлов совпадающих файлов, а не соответствующих строк (это также может улучшить скорость, учитывая, что grep перестает читать файл в первом совпадении с этой опцией ).
367
ответ дан enzotib 18 July 2018 в 08:05
поделиться

Лучше использовать

grep -rl "string" /path

, где опция

-r (или --recursive) используется для перемещения также всех подкаталогов /path , в то время как опция -l (или --files-with-matches) используется для печати только файлов совпадающих файлов, а не соответствующих строк (это также может улучшить скорость, учитывая, что grep перестает читать файл в первом совпадении с этой опцией ).
367
ответ дан enzotib 24 July 2018 в 16:43
поделиться
368
ответ дан enzotib 31 July 2018 в 19:46
поделиться
369
ответ дан enzotib 2 August 2018 в 14:33
поделиться
369
ответ дан enzotib 3 August 2018 в 17:00
поделиться
369
ответ дан enzotib 5 August 2018 в 01:45
поделиться
369
ответ дан enzotib 6 August 2018 в 18:52
поделиться
370
ответ дан enzotib 8 August 2018 в 23:15
поделиться
370
ответ дан enzotib 14 August 2018 в 17:30
поделиться

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

Если она недоступна, вы можете получить ее так:

mkdir -p ~/bin cd ~/bin wget http://sdjf.esmartdesign.com/files/rgrep chmod +x rgrep

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

I personnaly use

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

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

3
ответ дан Community 18 July 2018 в 08:05
поделиться

grep (GNU или BSD)

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

grep -r "pattern" .

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

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

grep "class foo" **/*.c

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

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

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

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

grep

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

rg "pattern" .

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

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

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

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

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

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

ack string

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

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

(Если у вас уже есть каталог ~/bin ], и это желательно в вашем PATH.)

11
ответ дан Konrad Rudolph 18 July 2018 в 08:05
поделиться

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

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

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

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

-type f указывает, что она должна обрабатывать только файлы, а не каталоги и т. Д. [F4] указывает, что для каждого найденного файла , он должен запустить команду grep, передав ей имя файла в качестве аргумента, заменив {} на имя файла
21
ответ дан Lance Roberts 18 July 2018 в 08:05
поделиться

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

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

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

Дополнительные параметры, которые я нахожу очень полезными: [ ! d6] -H заставляет печатать имя файла (подразумевается при поиске нескольких файлов) -F трактует search term как литерал, а не регулярное выражение -r делает рекурсивный поиск --color=always для создания цветов даже при прохождении через less. Чтобы сделать поддержку цветов less, вам необходимо использовать опцию -r: grep -Hrn search . | less -r -n заставляет напечатать номер строки

132
ответ дан Lekensteyn 18 July 2018 в 08:05
поделиться

Скрипт (find-in-code) для поиска в 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"
0
ответ дан nvd 18 July 2018 в 08:05
поделиться

Обновление 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 +

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

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

Вы можете попробовать следующий код; как функция в ваших .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

example:

$ 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;
2
ответ дан precise 18 July 2018 в 08:05
поделиться

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

grep -Rin string *

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

EDIT: для HVNSweeting, по-видимому, -R будет следовать символическим ссылкам, где, как -r, не будет.

17
ответ дан user606723 18 July 2018 в 08:05
поделиться

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

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

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

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

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

0
ответ дан Ztyx 18 July 2018 в 08:05
поделиться

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

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

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

1
ответ дан αғsнιη 18 July 2018 в 08:05
поделиться

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

Если она недоступна, вы можете получить ее так:

mkdir -p ~/bin cd ~/bin wget http://sdjf.esmartdesign.com/files/rgrep chmod +x rgrep

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

I personnaly use

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

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

3
ответ дан Community 24 July 2018 в 16:43
поделиться
  • 1
    rgrep предоставляется пакетом grep, который по умолчанию установлен в Ubuntu. – karel 2 January 2015 в 15:16

grep (GNU или BSD)

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

grep -r "pattern" .

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

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

grep "class foo" **/*.c

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

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

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

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

grep

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

rg "pattern" .

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

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

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

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

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

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

ack string

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

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

(Если у вас уже есть каталог ~/bin ], и это желательно в вашем PATH.)

11
ответ дан Konrad Rudolph 24 July 2018 в 16:43
поделиться
  • 1
    Или просто apt-get install ack-grep (и добавьте псевдоним ack = ack-grep в ваш .bashrc) – markijbema 1 August 2011 в 21:37
  • 2
    Что делают последние параметры для команды chmod? Являются ли они конкретными для chmod или связаны ли они с bash (часть !#:3)? – Elliott Darfink 21 January 2014 в 12:06
  • 3
    @ElliottDarfink Это использование функции истории Bash - ! является обозначением события . Они очень эффективны, чтобы избежать повторений. !#:3 ссылается на третий токен командной строки до сих пор, то есть ~/bin/ack в этом случае. – Konrad Rudolph 21 January 2014 в 18:59

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

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

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

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

-type f указывает, что она должна обрабатывать только файлы, а не каталоги и т. Д. [F4] указывает, что для каждого найденного файла , он должен запустить команду grep, передав ей имя файла в качестве аргумента, заменив {} на имя файла
21
ответ дан Lance Roberts 24 July 2018 в 16:43
поделиться
  • 1
    Для тех, кто не знает, добавление -name '*.py' ограничивает совпадения файлами, заканчивающимися на .py. – Daniel F 23 March 2014 в 03:10
  • 2
    Мне нравится, что это касается клиентов, которые не имеют -R, реализованных в их команде grep. – Aviose 11 August 2014 в 21:29

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

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

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

Дополнительные параметры, которые я нахожу очень полезными: [ ! d6] -H заставляет печатать имя файла (подразумевается при поиске нескольких файлов) -F трактует search term как литерал, а не регулярное выражение -r делает рекурсивный поиск --color=always для создания цветов даже при прохождении через less. Чтобы сделать поддержку цветов less, вам необходимо использовать опцию -r: grep -Hrn search . | less -r -n заставляет напечатать номер строки

132
ответ дан Lekensteyn 24 July 2018 в 16:43
поделиться
  • 1
    -H в папке избыточно, если есть более одного файла, как это возможно. Фактически, на странице man говорится -H, --with-filename: Print the file name for each match. This is the default when there is more than one file to search. – enzotib 1 August 2011 в 13:31
  • 2
    Я не знал этого, он всегда работал, как я и ожидал. Это моя команда по умолчанию при поиске файлов. – Lekensteyn 1 August 2011 в 13:34
  • 3
    Есть ли способ рассматривать файлы с расширением a. Скажем, .a (и объединить это с -r)? – user2413 5 November 2012 в 00:54
  • 4
    @ user2413 Попробуйте --include '*.*' – Lekensteyn 5 November 2012 в 17:24
  • 5
    @enzotib Просто FYI: я не получаю хороший чистый вывод каждой строки в каждом файле, где появляется мой текст с -rln или -rl, но я делаю это с -Hrn. Резервный или нет, это похоже на скриншот выше с параметрами -Hrn. Кроме того, это не похоже на -n работает без -H. – SgtPooki 25 March 2014 в 23:59

Скрипт (find-in-code) для поиска в 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"
0
ответ дан nvd 24 July 2018 в 16:43
поделиться

Обновление 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 +

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

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

Вы можете попробовать следующий код; как функция в ваших .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

example:

$ 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;
2
ответ дан precise 24 July 2018 в 16:43
поделиться
  • 1
    Сбой при именах файлов, содержащих пробелы. Недостаток скрывается из-за того, что stderr не отображается. – enzotib 13 January 2015 в 10:38
  • 2
    @enzotib спасибо, что указали, что это ... это еще не разрешено для указанной функции. Я добавил еще один лайнер, хотя .. – precise 13 January 2015 в 21:38
  • 3
    Теперь ответ аналогичен ответу @dmityugov. – enzotib 13 January 2015 в 22:28
  • 4
    да, но в этом смысле большинство ответов на этой странице, если вы проверяете, схожи по сравнению с тем, что они используют grep, рядом с тем, что является подмножеством, используя find с grep ... но если вы хотите принять разные переключатели и настройки как отличный ответ, возможно, мой тоже поместится здесь .. или вы отличаетесь? последнее обновление делает то, что я хотел бы в моем поиске: имена файлов с линиями с ключом поиска и номером строки. тоже :) и цветной выход и фильтр ошибок для лучшей читаемости. – precise 14 January 2015 в 07:44

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

grep -Rin string *

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

EDIT: для HVNSweeting, по-видимому, -R будет следовать символическим ссылкам, где, как -r, не будет.

17
ответ дан user606723 24 July 2018 в 16:43
поделиться
  • 1
    Для поиска в скрытых файлах запустите shopt -s dotglob (помните -s как «set & quot;»). Будьте осторожны при удалении файлов. Если у вас включен dotglob, rm -r * удаляет все в текущем каталоге, но также находится над ним, потому что .. соответствует. Чтобы отключить функцию dotglob, используйте shopt -u dotglob («unset»). Изменения являются временными, но они применимы только к текущей оболочке. – Lekensteyn 1 August 2011 в 20:09
  • 2
    Я забыл об этом. Есть ли способ установить его для одной линии? что-то вроде shopt -s dotglob & <grep cmd> & shopt -y dotglob только удобнее? Таким образом, нам не придется беспокоиться о его перезагрузке – user606723 1 August 2011 в 20:42
  • 3
    Кроме того, вероятно, легче использовать grep -Rin string . в большинстве этих случаев. Я просто использую *, потому что это кажется более естественным. – user606723 1 August 2011 в 20:44
  • 4
    shops -s dotglob;grep -Rin string *;shopt -u dotglob работает. – Lekensteyn 1 August 2011 в 20:56
  • 5
    да ... но .. было бы хорошо, если бы была команда, которая работала только для одной строки. вместо того, чтобы включать и выключать его в той же строке, где глупо – user606723 1 August 2011 в 21:13

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

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

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

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

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

0
ответ дан Ztyx 24 July 2018 в 16:43
поделиться

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

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

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

1
ответ дан αғsнιη 24 July 2018 в 16:43
поделиться
  • 1
    Использовать опцию xargs без опции -print0 для опции find и -0 до xargs не рекомендуется, имена файлов, содержащие пробелы, не будут выполняться. – enzotib 1 August 2011 в 16:45
  • 2
    @enzotib Я отредактировал ответ, как вы предложили. Пожалуйста, просмотрите и, если вам нужно отредактировать и исправить, я буду счастлив переделать вас. Спасибо – αғsнιη 13 January 2015 в 10:00
  • 3
    @KasiyA: теперь все в порядке, удалил мой downvote. – enzotib 13 January 2015 в 10:32
3
ответ дан Community 31 July 2018 в 19:46
поделиться

Другие вопросы по тегам:

Похожие вопросы: