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

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

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

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

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

6050
Nathan 6 Июн 2013 в 12:06

29 ответов

Лучший ответ

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

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.

11116
Intrastellar Explorer 26 Янв 2021 в 21:27

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

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: номер строки будет отображаться для совпадений

230
Vivek Ranjan 2 Апр 2018 в 08:35

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

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

ack 'text-to-find-here'

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

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


ОБНОВЛЕНИЕ

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

371
RAJ 12 Мар 2015 в 12:31

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

grep -Ril "text-to-find-here" /
  • i означает игнорирование регистра (в вашем случае необязательно).
  • R означает рекурсивный.
  • l означает «показывать имя файла, а не сам результат».
  • / означает запуск из корневого каталога вашей машины.
1720
fedorqui 'SO stop harming' 23 Фев 2016 в 10:02

Вы можете использовать команду ниже, так как вам не нужно имя файла, но вы хотите искать во всех файлах. Вот я захватываю форму "ТЕКСТ" Все файлы журнала, проверяя, что имя файла не печатается.

grep -e TEXT *.log | cut -d' ' --complement -s -f1

Grep с опцией -e довольно быстро по сравнению с другими опциями, так как это для соответствия ШАБЛОНА

12
Mitul Patel 10 Июл 2018 в 08:52

Приведенная ниже команда отлично подойдет для этого подхода:

find ./ -name "file_pattern_name"  -exec grep -r "pattern" {} \;
12
Peter Mortensen 16 Фев 2016 в 23:47

Все предыдущие ответы предполагают использование grep и find. Но есть другой способ: использовать Midnight Commander.

Это бесплатная утилита (30-летней давности, проверенная временем), визуальная, но не имеющая графического интерфейса. Он имеет множество функций, и поиск файлов - лишь одна из них.

13
Peter Mortensen 24 Апр 2019 в 15:28

Чтобы найти строку и вывести только эту строку со строкой поиска:

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;
13
user3124504user3124504 25 Янв 2014 в 11:08

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

http://linux.die.net/man/1/ack

ack -i search_string folder_path/*

Вы можете игнорировать -i для поиска с учетом регистра

14
Daniel 13 Июл 2017 в 00:17

Использование:

grep -c Your_Pattern *

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

14
Peter Mortensen 25 Май 2017 в 00:13

grep - ваш хороший друг для достижения этой цели.

grep -r <text_fo_find> <directory>

Если вас не волнует регистр текста, который нужно найти, используйте:

grep -ir <text_to_find> <directory>
15
Peter Mortensen 27 Мар 2020 в 01:00

Я написал сценарий Python, который делает нечто подобное. Вот как следует использовать этот скрипт.

./sniff.py path pattern_to_search [file_pattern]

Первый аргумент, path, - это каталог, в котором мы будем выполнять рекурсивный поиск. Второй аргумент, pattern_to_search, является регулярным выражением, которое мы хотим искать в файле. Мы используем формат регулярных выражений, определенный в библиотеке Python re. В этом скрипте . также соответствует новой строке.

Третий аргумент, file_pattern, необязательный. Это еще одно регулярное выражение, которое работает с именем файла. Будут рассмотрены только те файлы, которые соответствуют этому регулярному выражению.

Например, если я хочу выполнить поиск файлов Python с расширением py, содержащим Pool(, за которым следует слово Adaptor, я делаю следующее:

./sniff.py . "Pool(.*?Adaptor"  .*py
./Demos/snippets/cubeMeshSigNeur.py:146 
./Demos/snippets/testSigNeur.py:259 
./python/moose/multiscale/core/mumbl.py:206 
./Demos/snippets/multiComptSigNeur.py:268 

И вуаля, он генерирует путь к совпадающим файлам и номер строки, в которой было найдено совпадение. Если найдено более одного совпадения, то к имени файла будет добавлен номер каждой строки.

15
Peter Mortensen 30 Июн 2014 в 17:59

Простой find может пригодиться. укажите псевдоним в вашем файле ~/.bashrc:

alias ffind find / -type f | xargs grep

Запустите новый терминал и выдайте:

ffind 'text-to-find-here'
16
Peter Mortensen 25 Май 2017 в 00:15

Пытаться:

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' {} \;
16
kenorb 9 Май 2015 в 09:49

Я очарован тем, насколько просто 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

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

17
Peter Mortensen 27 Мар 2020 в 01:01

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

Немного расширить 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 обрабатывать путь и имя файла как одну строку, а не разбивать ее на каждый пробел.
18
Peter Mortensen 25 Май 2017 в 00:03
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
18
JuanZe 26 Ноя 2014 в 13:12

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

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
20
Atul Arvind 1 Фев 2014 в 05:47

Если вы строго хотите использовать 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, чтобы улучшить поиск файлов.

21
JMP 21 Ноя 2020 в 13:37

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

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

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

21
Peter Mortensen 25 Май 2017 в 00:10

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

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

grep -RIl "" .

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

22
Peter Mortensen 25 Май 2017 в 00:01

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

grep -rnw `pwd` -e "pattern"

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

grep -rnw -e "pattern"

Или

grep -rnw "pattern"

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

31
mahatmanich 2 Фев 2017 в 12:29

Пытаться:

find . -name "*.txt" | xargs grep -i "text_pattern"
34
kenorb 17 Апр 2015 в 15:33

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

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

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


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

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

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

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

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

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

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

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

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

ack :

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

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


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

43
Bludzee 2 Июн 2018 в 17:21

Появилась новая утилита The Silversearcher .

sudo apt install silversearcher-ag

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

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

ag "Search query"

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

47
Neil Agarwal 23 Июл 2019 в 17:01
grep -insr "pattern" *
  • i: игнорировать различия в регистре как в ШАБЛОНЕ, так и во входных файлах.
  • n: префикс каждой строки вывода с помощью номера строки с отсчетом от 1 внутри входного файла.
  • s: подавлять сообщения об ошибках о несуществующих или нечитаемых файлах.
  • r: рекурсивное чтение всех файлов в каждом каталоге.
47
Fabio Poloni 8 Мар 2016 в 07:39

Если ваш 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 - выводить только совпавшую строку (не имя файла)
60
RobEarl 12 Авг 2015 в 09:19

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

Прежде всего, я считаю, что вы использовали -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, чтобы игнорировать регистр. Дополнительную информацию можно прочитать здесь.

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

86
lkamal 7 Окт 2017 в 05:54

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

grep -inr "Text" folder/to/be/searched/
128
Sudipta 31 Июл 2013 в 14:09