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

Я пытаюсь найти способ просканировать всю мою систему Linux на предмет всех файлов, содержащих определенную строку текста. Чтобы уточнить, я ищу текст внутри файла, а не в имени файла.

Когда я искал, как это сделать, я дважды наткнулся на это решение:

find / -type f -exec grep -H 'text-to-find-here' {} \;

Однако это не работает. Кажется, отображает каждый файл в системе.

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

Ответов (25)

Решение

Сделайте следующее:

grep -rnw '/path/to/somewhere/' -e 'pattern'
  • -rили -Rрекурсивно,
  • -n номер строки, а
  • -w означает соответствие всему слову.
  • -l (L в нижнем регистре) можно добавить, чтобы просто указать имя файла для совпадающих файлов.
  • -e шаблон, используемый во время поиска

Наряду с этим, --exclude, --include, --exclude-dir флаги могут быть использованы для эффективного поиска:

  • Это будет искать только те файлы, которые имеют расширения .c или .h:
grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e "pattern"
  • Это исключит поиск всех файлов с расширением .o:
grep --exclude=\*.o -rnw '/path/to/somewhere/' -e "pattern"
  • Для каталогов можно исключить один или несколько каталогов с помощью --exclude-dirпараметра. Например, это исключит каталоги dir1 /, dir2 / и все они, соответствующие * .dst /:
grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"

Это очень хорошо работает для меня, достигая почти той же цели, что и ваша.

Для получения дополнительных опций проверьте man grep .

Вы можете использовать ack . Это похоже на grep для исходного кода. С его помощью вы можете сканировать всю файловую систему.

Просто делать:

ack 'text-to-find-here'

В вашем корневом каталоге.

Вы также можете использовать регулярные выражения , указать тип файла и т. Д.


ОБНОВИТЬ

Я только что обнаружил Silver Searcher , который похож на ack, но в 3-5 раз быстрее его и даже игнорирует шаблоны из .gitignore файла.

Вот несколько списков команд, которые можно использовать для поиска файла.

grep "text string to search” directory-path

grep [option] "text string to search” directory-path

grep -r "text string to search” directory-path

grep -r -H "text string to search” directory-path

egrep -R "word-1|word-2” directory-path

egrep -w -R "word-1|word-2” directory-path

Вы можете использовать:

grep -r "string to be searched"  /path/to/dir

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

Или команду, аналогичную той, которую вы пытаетесь выполнить (пример :) для поиска во всех файлах javascript (* .js):

find . -name '*.js' -exec grep -i 'string to search for' {} \; -print

Это напечатает строки в файлах, где появляется текст, но не напечатает имя файла.

В дополнение к этой команде мы также можем написать это: grep -rn «Строка для поиска» / путь / к / каталогу / или / файлу -r: рекурсивный поиск n: для совпадений будет отображаться номер строки

grep можно использовать, даже если мы не ищем строку.

Просто бегаю,

grep -RIl "" .

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

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

find / -type f | xargs grep 'text-to-find-here'

Мне это легче запомнить, чем формат find -exec .

Это выведет имя файла и содержимое совпавшей строки, например

/home/rob/file:text-to-find-here

Необязательные флаги, которые вы можете добавить к grep :

  • -i - поиск без учета регистра
  • -l - выводить только имя файла, в котором было найдено совпадение
  • -h - выводить только совпавшую строку (не имя файла)
find /path -type f -exec grep -l "string" {} \;

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

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

-type f specifies that it should proceed only files, not directories etc.
-exec grep specifies that for every found file, it should run grep command, passing its filename as an argument to it, by replacing {} with the filename

Надеюсь, это поможет ...

Расширение grep немного , чтобы дать больше информации на выходе, например, чтобы получить номер строки в файле , где текст может быть сделан следующим образом :

find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"

И если у вас есть представление о типе файла, вы можете сузить область поиска, указав расширения типа файла для поиска, в данном случае .pas ИЛИ .dfm файлы:

find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext"

Краткое объяснение опций:

  1. .в findуказывает из текущего каталога.
  2. -name« *.*»: Для всех файлов (-name « *.pas» -o -name « *.dfm»): только *.pasИЛИ *.dfmфайлы, или указаны с-o
  3. -type f указывает, что вы ищете файлы
  4. -print0а --nullс другой стороны |(канала) - решающие, передавая имя файла от findк grepвстроенному в xargs, позволяя передавать имена файлов С пробелами в именах файлов, позволяя grep обрабатывать путь и имя файла как одну строку, и не разбивать его на каждое место.

Вы можете использовать grep -ilR :

grep -Ril "text-to-find-here" /
  • i означает игнорировать регистр (в вашем случае необязательно).
  • R означает рекурсивный.
  • l означает «показывать имя файла, а не сам результат».
  • / означает запуск из корневого каталога вашей машины.

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

Я дважды сталкивался с этим решением:

find / -type f -exec grep -H 'text-to-find-here' {} \;


Если вы используете find, как в вашем примере, лучше добавить -s ( --no-messages ) в grep и 2>/dev/null в конце команды, чтобы избежать большого количества сообщений об отказе в разрешении, выдаваемых grep и find :

find / -type f -exec grep -sH 'text-to-find-here' {} \; 2>/dev/null

find - это стандартный инструмент для поиска файлов в сочетании с grep при поиске определенного текста на Unix-подобных платформах. Находкой команда часто сочетается с xargs , кстати.

Для той же цели существуют более быстрые и простые инструменты - см. Ниже. Лучше попробуйте их, конечно , при условии, что они доступны на вашей платформе :

Более быстрые и простые альтернативы

RipGrep - самый быстрый инструмент поиска:

rg 'text-to-find-here' / -l

Серебряный искатель :

ag 'text-to-find-here' / -l

подтверждение :

ack 'text-to-find-here' / -l

Примечание: вы также можете добавить 2>/dev/null к этим командам, чтобы скрыть многие сообщения об ошибках.


Предупреждение : если вы действительно не можете этого избежать, не выполняйте поиск из '/' (корневого каталога), чтобы избежать длительного и неэффективного поиска! Поэтому в приведенных выше примерах вам лучше заменить ' / ' на имя подкаталога, например, «/ home», в зависимости от того, где вы действительно хотите искать ...

Вы можете использовать это:

grep -inr "Text" folder/to/be/searched/
grep -insr "pattern" *
  • i: Игнорировать различия в регистре как в ШАБЛОНЕ, так и во входных файлах.
  • n: Префикс каждой строки вывода с помощью номера строки с отсчетом от 1 внутри входного файла.
  • s: Подавлять сообщения об ошибках о несуществующих или нечитаемых файлах.
  • r: Рекурсивно читать все файлы в каждом каталоге.

Список имен файлов, содержащих заданный текст

Во-первых, я считаю, что вы использовали -H вместо -l . Также вы можете попробовать добавить текст в кавычки, за которыми следует {} \ .

find / -type f -exec grep -l "text-to-find-here" {} \; 

Пример

Допустим, вы ищете файлы, содержащие определенный текст «Лицензия Apache» внутри вашего каталога. Он будет отображать результаты, несколько похожие на показанные ниже (вывод будет отличаться в зависимости от содержимого вашего каталога).

bash-4.1$ find . -type f -exec grep -l "Apache License" {} \; 
./net/java/jvnet-parent/5/jvnet-parent-5.pom
./commons-cli/commons-cli/1.3.1/commons-cli-1.3.1.pom
./io/swagger/swagger-project/1.5.10/swagger-project-1.5.10.pom
./io/netty/netty-transport/4.1.7.Final/netty-transport-4.1.7.Final.pom
./commons-codec/commons-codec/1.9/commons-codec-1.9.pom
./commons-io/commons-io/2.4/commons-io-2.4.pom
bash-4.1$ 

Убрать чувствительность к регистру

Даже если вы не используете регистр вроде «текст» или «ТЕКСТ», вы можете использовать -i переключатель, чтобы игнорировать регистр. Вы можете прочитать более подробную информацию здесь .

Надеюсь, это вам поможет.

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

grep -rnw `pwd` -e "pattern"

Обновление В зависимости от версии grep, которую вы используете, вы можете опустить pwd . В более новых версиях, . похоже, это вариант по умолчанию для grep, если каталог не указан таким образом:

grep -rnw -e "pattern"

или

grep -rnw "pattern"

будет делать то же самое, что и выше!

Появилась новая утилита под названием The Silversearcher.

sudo apt install silversearcher-ag

Он тесно работает с Git и другими VCS. Таким образом, вы ничего не получите в .git или другом каталоге.

Вы можете просто использовать

ag "Search query"

И он сделает эту задачу за вас!

Silver Searcher - потрясающий инструмент, но ripgrep может быть даже лучше.

Он работает в Linux, Mac и Windows и был написан на Hacker News пару месяцев назад (здесь есть ссылка на блог Эндрю Галланта, в котором есть ссылка на GitHub):

Ripgrep - новый инструмент поиска в командной строке

Пытаться:

find . -name "*.txt" | xargs grep -i "text_pattern"

Я очарован тем, насколько просто grep делает это с помощью rl:

grep -rl 'pattern_to_find' /path/where/to/find

-r to recursively find a file / directory inside directories..
-l to list files matching the 'pattern'

Используйте '-r' без 'l', чтобы увидеть имена файлов, за которыми следует текст, в котором найден шаблон !

grep -r 'pattern_to_find' /path/where/to/find

Работает просто отлично ...

Если вы строго хотите использовать, find используйте find + grep :

find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;

Шаги :

  1. Используйте findдля поиска файлов,
  2. Выполните grepвсе.

Это дает вам возможность find находить файлы.

  • Используйте, -name Patternесли хотите grepтолько определенные файлы:

find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;

Вы можете использовать различные опции find для улучшения поиска файлов.

Вы также можете использовать awk :

awk '/^(pattern)/{print}' /path/to/find/*

pattern - это строка, которую вы хотите сопоставить в файлах.

grep -lrnw '/root/Desktop/ipozal' -e 'geolocation'

Пожалуйста, настройте команду ниже в соответствии с требованиями и рекурсивно найдите любую строку из файлов.

grep -i hack $(find /etc/ -type f)

Если вы находитесь в репозитории git, вы можете использовать:

git grep something

Пытаться:

find / -type f -exec grep -H 'text-to-find-here' {} \;

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

Для домашней папки используйте:

find ~/ -type f -exec grep -H 'text-to-find-here' {} \;

Для текущей папки используйте:

find ./ -type f -exec grep -H 'text-to-find-here' {} \;

grep( GNU или BSD )

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

grep -r "class foo" .

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

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

grep "class foo" **/*.c

Примечание. Используя параметр подстановки ( **), он рекурсивно сканирует все файлы с определенным расширением или шаблоном. Чтобы включить этот синтаксис, выполните следующую команду: shopt -s globstar. Вы также можете использовать **/*.*для всех файлов (кроме скрытых и без расширения) или любой другой шаблон.

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

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

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

ripgrep

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

rg "class foo" .

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

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

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


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

  • -i - Бесчувственный поиск.
  • -I - Игнорировать двоичные файлы.
  • -w - Искать слова целиком (в отличие от частичного сопоставления слов).
  • -n - Покажи линию твоего матча.
  • -C/ --context(например -C5) - увеличивает контекст, чтобы вы могли видеть окружающий код.
  • --color=auto - Отметьте соответствующий текст.
  • -H - Отображает имя файла, в котором находится текст.
  • -c- Отображает количество совпадающих строк. Можно комбинировать с -H.