Вопрос: Как использовать команду «grep» для поиска текста, включая подкаталоги


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


286
2017-08-01 11:38


Источник


grep -RIn <yor pattern> * Будет искать из текущих каталогов во всех текстовых файлах. Не уверен, как сделать рекурсивно поиск в файлах, например, * .C только с grep
Подстановочный знак с --include="*.C" option, @ user311346, благодаря @Lekensteyn. - Bob Stein
Используйте комбинацию find и grep для рекурсивного поиска файлов для строки в текущей и всех подкаталогах. Проверь это wilddiary.com/find-files-containing-my-text - Drona


Ответы:


Было бы лучше использовать

grep -rl "string" /path

где

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

370
2017-08-01 11:55



На самом деле, если «строка» является текстовым шаблоном для поиска, лучше использовать эту функциональность, иначе кто-то может столкнуться с проблемами, когда строка содержит точку или специальный символ, который имеет смысл в регулярных выражениях, а не только точку, которая должна быть найдена как строка , как есть. Тогда я буду использовать -rlF переключатели, -F для «фиксированной строки» (а не для регулярного выражения), например). Конечно, если в задаче использовались регулярные выражения, то извините меня. Конечно, в той же теории без -r, я часто вижу, что люди принимают grep-поиск «текста», и это может вызвать проблемы, особые из которых означают что-то как регулярное выражение. - LGB
Существует также -i флаг, который игнорирует случай. - Marco Ceppi♦
Я бы только показал --recursive вариант, есть много вариантов и сценариев использования, о которых можно говорить. Я начал с принятого ответа @dmityugov и модифицировал работу без find, - enzotib
@ N.N .: сделано :-) - enzotib
@ScottBiggs: с опцией --include '*.h' - enzotib


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

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,

Example output


135
2017-08-01 12:27



-H в папке избыточно, если есть более одного файла, как это возможно. Фактически, на странице человека говорится -H, --with-filename: Print the file name for each match. This is the default when there is more than one file to search. - enzotib
Я не знал этого, он всегда работал, как я и ожидал. Это моя команда по умолчанию при поиске файлов. - Lekensteyn
Есть ли способ рассматривать файлы только с расширением a. (И сочетать это с -r)? - user2413
@ user2413 Попробуйте --include '*.*' - Lekensteyn
@enzotib Просто FYI: я не получаю хороший чистый вывод каждой строки в каждом файле, где появляется мой текст с -rln или -rl, но я делаю это с -Hrn. Резервный или нет, это похоже на скриншот выше с параметрами -Hrn. Кроме того, это не похоже на -n работает без -H. - SgtPooki


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

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

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

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

  • -type f указывает, что он должен обрабатывать только файлы, а не каталоги и т. д.
  • -exec grep указывает, что для каждого найденного файла он должен запускать команду grep, передавая ее имя файла в качестве аргумента для него, заменяя {} с именем файла

21
2017-08-01 11:48



Только для тех, кто не знает, добавляя -name '*.py' ограничивает совпадения с файлами, заканчивающимися на .py. - Daniel F
Мне нравится, что это касается клиентов, которые не имеют -R, реализованных в их команде grep. - Aviose


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

grep -Rin string *

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

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


17
2017-08-01 14:43



Чтобы выполнить поиск в скрытых файлах, запустите shopt -s dotglob (запомнить -s актив"). Будьте осторожны при удалении файлов. Если у вас включен dotglob, rm -r * удаляет все в текущем каталоге, но такжекаталог выше, потому что .. Матчи. Чтобы отключить функцию dotglob, используйте shopt -u dotglob ( "Отключено"). Изменения являются временными, но они применимы только к текущей оболочке. - Lekensteyn
Я забыл об этом. Есть ли способ установить его для одной линии? что-то вроде shopt -s dotglob & <grep cmd> & shopt -y dotglob только удобнее? Таким образом, нам не придется беспокоиться о его перезагрузке - user606723
Кроме того, это, вероятно, проще в использовании grep -Rin string . в большинстве случаев. Я просто использую *, потому что это кажется более естественным. - user606723
shops -s dotglob;grep -Rin string *;shopt -u dotglob работает. - Lekensteyn
да ... но .. было бы хорошо, если бы была команда, которая работала только для одной строки. вместо того, чтобы включать и выключать его в той же строке, где глупо - user606723


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

ack string

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

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

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


11
2017-08-01 15:09



Или просто apt-get install ack-grep (и добавьте псевдоним ack = ack-grep в ваш .bashrc) - markijbema
Каковы последние параметры для chmod команда делает? Являются ли они конкретными для chmod или они связаны с bash ( !#:3 часть)? - Elliott Darfink
@ElliottDarfink Это использование Bash's история - ! является обозначение события, Они очень эффективны, чтобы избежать повторений. !#:3 ссылается на третий токен командной строки до сих пор, т. е. ~/bin/ack в этом случае. - Konrad Rudolph


Команда 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 с цветом


3
2018-01-02 13:58



rgrep предоставляется пакетом grep, который по умолчанию установлен в Ubuntu. - karel


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

Пример, приведенный ниже: snap1


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

2
2018-01-25 11:11



Сбой при именах файлов, содержащих пробелы. Недостаток скрывается из-за того, что stderr не отображается. - enzotib
@enzotib спасибо, что указали, что это ... это еще не разрешено для указанной функции. Я добавил еще один лайнер, хотя .. - precise
Теперь ответ аналогичен ответу @dmityugov. - enzotib
да, но в этом смысле большинство ответов на этой странице, если вы проверяете, похожи на то, что они используют grep, рядом с тем, что является подмножеством, использующим find с grep... но если вы хотите принять разные переключатели и настройки как отдельный ответ, возможно, мой тоже поместится здесь ... или вы будете отличаться? последнее обновление делает то, что я хотел бы в моем поиске: имена файлов с линиями с ключом поиска и номером строки. тоже :) и цветной выход и фильтр ошибок для лучшей читаемости. - precise


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

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

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


1
2017-08-01 15:30



С помощью xargs без -print0 вариант find а также -0 вариант xargs устарел, он будет терпеть неудачу при именах файлов, содержащих пробелы. - enzotib
@enzotib Я отредактировал ответ, как вы предложили. Пожалуйста, просмотрите и, если вам нужно отредактировать и исправить, я буду счастлив переделать вас. Спасибо - αғsнιη
@KasiyA: теперь все в порядке, удалил мой downvote. - enzotib