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

5260

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

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

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

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

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

Натан
источник
21
помните, что grep будет интерпретировать любой .как подстановочный знак с одним символом, среди других. Мой совет: всегда используйте fgrep или egrep.
Уолтер Тросс
10
во всяком случае, вы были почти там! Просто замените -Hна -l(и, возможно, grepна fgrep). Чтобы исключить файлы с определенными шаблонами имен, вы должны использовать findболее сложный способ. Однако стоит научиться пользоваться find. Просто man find.
Уолтер Тросс
6
find … -exec <cmd> +легче набрать и быстрее, чем find … -exec <cmd> \;. Это работает, только если <cmd>принимает любое количество аргументов имени файла. Экономия времени выполнения особенно велика, если <cmd>запускать медленно, как скрипты Python или Ruby.
Гагелло
Чтобы выполнить нерекурсивный поиск по заданному пути, введите команду `grep --include = *. Txt -snw" pattern "thepath / *.
Стефан Лоран
@ StéphaneLaurent Я думаю, ты слишком усложняешь это. Просто скажиgrep "pattern" path/*.txt
Федорки "ТАК прекрати вредить"

Ответы:

9524

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

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

Наряду с этим, --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параметр. Например, это исключит dirs dir1 /, dir2 / и все они будут соответствовать * .dst /:

    grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"
    

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

Для более подробной информации проверьте man grep.

rakib_
источник
74
используйте --exclude. как "grep -rnw --exclude = *. o 'directory' -e" pattern "
rakib_
98
Стоит отметить: кажется, что rопция ленивая (сначала проходит по глубине, затем останавливается после первого каталога), но Rявляется жадной (будет правильно проходить по всему дереву).
Элиран Малка
5
grep -rnw "Строка, которую я искал", сделал то, что мне было нужно. Спасибо!
ViliusK
33
Примечание (особенно для новичков): кавычки в приведенной выше команде важны.
madD7
69
@Eliran Malka Ren rбудет проходить оба каталога правильно, но Rбудет следовать символическим ссылкам.
bzeaman
1502

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

grep -Ril "text-to-find-here" /
  • i означает игнорировать регистр (необязательно в вашем случае).
  • R обозначает рекурсивный.
  • l расшифровывается как «показать имя файла, а не сам результат».
  • / обозначает начало в корне вашей машины.
Федорки "ТАК прекратить вредить"
источник
85
Судя по моему опыту, -iон сильно замедляется, поэтому не используйте его, если не нужно. Проверьте это в определенном каталоге, а затем обобщите. Это должно быть завершено в течение нескольких минут. Я думаю, что регулярное выражение сделало бы это медленнее. Но мои комментарии основаны на предположениях, я предлагаю вам проверить это timeперед строкой.
Федорки "ТАК прекратить причинять вред"
4
Да, /*стоит за это. Во всяком случае, я просто проверил это и заметил, что просто /работает.
Федорки "ТАК прекратить причинять вред"
10
Если вы не используете регулярное выражение для поиска, вы можете использовать fgrep вместо grep в большинстве систем.
markle976
8
Да @ markle976, на самом деле от человека Grep: fgrep is the same as grep -F -> Interpret PATTERN as a list of fixed strings.
Федорки "ТАК прекратить причинять вред"
17
Вы можете заменить / на путь к каталогу grep -Ril "text-to-find-here" ~/sites/или использовать. для текущего каталогаgrep -Ril "text-to-find-here" .
Black
330

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

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

ack 'text-to-find-here'

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

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


ОБНОВИТЬ

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

Stephan
источник
57
Очень полезно, просто и быстро. Предупреждение: «В дистрибутивах, производных от Debian, ack упакован как« ack-grep », потому что« ack »уже существует» (from beyondgrep.com/install ). Вы можете в конечном итоге запустить конвертер кода Кандзи на этих
Linux-системах
11
У ack или ack-grep есть хорошие моменты, но при правильном использовании find + grep намного лучше в производительности
Sławomir Lenart
14
Обратите внимание, что ripgrep работает быстрее, чем все остальное, упомянутое здесь, включая Silver Searcher и plain 'ol grep. Смотрите этот пост в блоге для доказательства.
Радон Росборо
195

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

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 "String to search" / path / to / directory / или / file -r: рекурсивный поиск n: номер строки будет показан для совпадений

learner_19
источник
1
Спасибо за поиск версии. В моей версии grep (busybox для NAS) нет опции -r, мне действительно нужно другое решение!
х
3
Спасибо за версию «найти»! Очень важно иметь возможность фильтровать по « .js» или « .txt» и т. Д. Никто не хочет тратить часы на ожидание, пока grep завершит поиск всех мультигигабайтных видео с последнего семейного отпуска, даже если команда легче набрать.
mightypile
лучше grep чем принятая версия, потому что принято не искать половину слов
waza123
115

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

grep -inr "Text" folder/to/be/searched/
Арканзас
источник
12
самый простой, многословный, рекурсивный и нечувствительный к регистру. недурно.
Франческо Касула
если вы добавите -A3 еще лучше
albanx
74

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

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

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

lkamal
источник
2
Вот что делает эта команда: findпередаст все пути, которые она найдет, команде grep -l "text-to-find-here" <file found>". Вы можете добавить ограничения к имени файла, например, find / -iname "*.txt"для поиска только в файлах, имя которых заканчивается.txt
Mene
1
@Auxiled - включает пример вывода, чтобы избежать путаницы для читателей.
17
2
@Mene Это действительно печальное утверждение, что комментарий Вспомогательного имеет больше голосов, чем ваш ... даже если их комментарий от 2014 года, а ваш комментарий 2017 года, что у их комментария есть 6, когда у него должно быть ровно 0, а у вашего только один (теперь два) нет. Я бы не хотел в это верить.
Прифтан
@Mene То, что говорится -iname, нечувствительно к регистру, что означает, что он также найдет, например, файлы .TXT, а также TxT и TXt и так далее.
Прифтан
66

grep( GNU или BSD )

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

grep -r "class foo" .

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

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

grep "class foo" **/*.c

Примечание. Используя параметр globbing ( **), он рекурсивно сканирует все файлы с определенным расширением или шаблоном. Чтобы включить этот синтаксис, выполните следующую команду: 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.
kenorb
источник
1
Я также считаю полезной расширенную глобализацию. Но имейте в виду, что если файлов действительно очень много, вы можете получить ошибку «Список аргументов слишком длинный». (Простое шатание также склонно к такого рода ошибкам).
Йори Н.
2
Для вдыхания всей файловой системы rg будет гораздо менее болезненным, чем почти любой другой инструмент.
лк
55

Если ваш 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 - выводить только строку, которая соответствует (не имя файла)
RobEarl
источник
3
Это эквивалентно grep 'text-to-find-here'без имени файла, если findничего не находит. Это будет зависать и ждать ввода пользователя! Добавить --no-run-if-emptyв качестве опции xargs.
Гагелло
3
Эта комбинация find и xargs не работает должным образом, если имена файлов или каталогов содержат пробелы (символы, которые xargs интерпретирует как разделители). Использование find … -exec grep … +. Если вы настаиваете на использовании find вместе с xargs, используйте -print0и -0.
Гагелло
43
grep -insr "pattern" *
  • i: Игнорировать различия регистра как в PATTERN, так и во входных файлах.
  • n: Добавьте к каждой строке выходных данных номер строки на основе 1 в своем входном файле.
  • s: Подавлять сообщения об ошибках несуществующих или нечитаемых файлов.
  • r: Рекурсивно читать все файлы в каждом каталоге.
enfinet
источник
3
Можете ли вы объяснить, как ваш ответ улучшается по сравнению с другими ответами или насколько он сильно отличается от них?
Амос М. Карпентер
не слишком сложный для запоминания, он будет охватывать все шаблоны (case-senstivity -> off, включает в себя имена файлов и номера строк, будет выполнять рекурсивный поиск и т. д.), а использование «*» в конце будет выполнять поиск во всех каталогах (не нужно указывать какие-либо путь или имя каталога).
enfinet
Извините, мне следовало быть более ясным: было бы здорово, если бы вы включили это объяснение в свой ответ. В нынешнем виде, особенно с таким множеством подобных ответов, трудно понять из такого короткого ответа, какая польза от него перед принятым или одним из одобренных.
Амос М. Карпентер
6
@ AmosM.Carpenter Одна вещь, которая мне нравится в этом ответе, это указание на аргумент подавления, который может помочь отфильтровать шум, который не имеет значения для получения желаемых результатов. Grep печатает такие ошибки, как «Функция не реализована», «Недопустимый аргумент», «Ресурс недоступен» и т. Д. И т. Д. На определенных «файлах».
leetNightshade
@leetNightshade: Я предполагаю, что вы обращаетесь ко мне со своим комментарием, потому что я попросил объяснения по поводу редкого оригинального сообщения. Пожалуйста, ознакомьтесь с большим пересмотром Фабио для моих предыдущих комментариев, чтобы иметь смысл.
Амос М. Карпентер
39

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

sudo apt install silversearcher-ag

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

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

ag "Search query"

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

Нил Агарвал
источник
35

Как найти все файлы, содержащие определенный текст в 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", в зависимости от того, где вы действительно хотите искать ...

Bludzee
источник
«find - это стандартный инструмент для поиска файлов, содержащих определенный текст на Unix-подобных платформах» , мне кажется довольно двусмысленным. Даже кроме того, что рекурсивно grep findне ищет непосредственно внутри файлов текст. И, может быть, эти дополнительные инструменты полезны для некоторых, но старых таймеров, и те, к кому хорошо привыкли, например grep, не дадут им вообще никакого времени (ну, конечно, я не буду). Не говоря, что они бесполезны.
Прифтан
«.... содержащий конкретный текст ...»: эта часть предложения не была точной (потому что она не находит себя связанной с этой частью поиска). Ред. Спасибо.
Блудзее
Рад помочь! Единственное, что очень быстро бросается в глаза, - это поменять папку слова на каталог, но я знаю, что это мой крестовый поход, который я никогда не выиграю полностью. Не сдаваться, хотя ...
Прифтан
Почему не «каталог» вместо «папка», но почему? Пожалуйста, поделитесь своим "крестовым походом"!
Блудзее
Я говорю использовать каталог вместо! Ссылаясь на: вам лучше заменить «/» на имя подпапки. И это моя любимая мозоль .. особенно, потому что даже Windows назвала его «каталогом». Ах ... может быть, вы это поняли. Почему? Ну, потому что это так называется. Это также называется на уровне файловой системы. И посмотрите на это так: когда-либо это называлось (для DOS) fol? Нет, конечно нет; это называлосьdir (и я верю, что это все еще). Папка - вещь, придуманная (я полагаю) удобством для пользователя, хотя в этом случае она, возможно, притупляет ее для менее «продвинутых» пользователей?
Прифтан
29

Пытаться:

find . -name "*.txt" | xargs grep -i "text_pattern"
Venkat
источник
5
Это на самом деле яркий пример того, когда НЕ использовать, xargsкак это .. рассмотреть это. echo "file bar.txt has bar" > bar.txt; echo "file foo bar.txt has foo bar" > "foo bar.txt"; echo "You should never see this foo" > foo; find . -name "*.txt" | xargs grep -i foo # ./foo:You should never see this foo, xargsЗдесь соответствуют не тому файлу и не соответствуют намеченному файлу. Либо использовать, find .. -print0 | xargs -0 ...но это бесполезное использование трубы или лучшеfind ... -exec grep ... {} +
шаломба
29

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

grep -rnw `pwd` -e "pattern"

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

grep -rnw -e "pattern"

или

grep -rnw "pattern"

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

mahatmanich
источник
3
использование pwdвообще не обязательно, так как это значение по умолчанию. grep -rnw "pattern"достаточно.
Федорки 'ТАК прекрати вредить'
и на самом деле, и то же самое grep -rnw, что было дано три года назад, я не вижу, как этот ответ добавляет ценность.
Федорки 'ТАК прекрати вредить'
Выбранный ответ не показывает шаблон по умолчанию, и 5 человек, кажется, нашли его полезным
mahatmanich
Что вы имеете в виду под «шаблоном по умолчанию»? Принятый ответ содержит grep -rnw '/path/to/somewhere/' -e "pattern"то, что у вас есть здесь. 5 голосов после 2,3 млн посещений не так уж много значит.
Федорки 'ТАК прекрати вредить'
Я согласен :-) в исходном ответе мне не хватало варианта использования, при котором вам вообще не нужно указывать путь или рекурсивно искать в текущем каталоге, что не отражено в принятом ответе. Таким образом, это был хороший опыт изучения grep, чтобы копать немного глубже.
Махатманич
19

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

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

grep -RIl "" .

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

Алекс Жасмин
источник
2
Я не понимаю, как это лучше, чем использовать простое lsили find(для рекурсивного)
fedorqui «ТАК Хватит вредить»
17

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

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
Атул Арвинд
источник
5
что это добавляет к существующим ответам?
Федорки "ТАК прекратить вредить"
@fedorqui egrepэквивалентен, grep -Eи это означает, что --extended-regexpвы можете найти подробности здесь unix.stackexchange.com/a/17951/196072
omerhakanbilici
15
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
Винод Джоши
источник
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' {} \;
user4863663
источник
Возможно, детали различий в папках очевидны для многих ... но также очень полезны для новичков. +1
нилон
1
что это добавляет к существующим ответам?
Федорки 'ТАК прекрати вредить'
Назовите это моим крестовым походом, но слово «каталог». Это не Windows (которая в любом случае использовала директорию - до 9x). Пожалуйста, перестаньте говорить «папка». Что касается вашей последней команды, вам даже не нужен '/' только FYI.
Прифтан
15

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

Развернуть 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 относиться путь и имя файла , как одну строку, и не разбивайте его на каждом пространстве.
Герт ван Бильон
источник
-name '*.*'не то, что вы говорите; он не обнаружит файл с именем «file», потому что шаблон не соответствует этому (нет .ext); *однако (хорошо. файлы в стороне). Но есть еще одна вещь: если вам нужны все файлы, зачем вообще указывать имя файла? Никаких других комментариев - за исключением того, что приятно знать, что все еще есть люди, которые не используют терминологию «папка» в терминологии MS (которую, на самом деле, после того, как я сказал это достаточно, я бы не стал добавлять, но я хотел бы отметить слегка неверное заявление, которое вы сделали с именами файлов - а также избыточность / бесполезность в случае «все»).
Прифтан
15

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

alias ffind find / -type f | xargs grep

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

ffind 'text-to-find-here'
висячий указатель
источник
14

Я написал скрипт 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 

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

Дилавар
источник
14

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

BreakBadSP
источник
В чем разница? Будет ли работать с пробелами в пути к файлу?
Питер Мортенсен
13

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

grep -c Your_Pattern *

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

Dr_Hope
источник
13

grep - ваш хороший друг, чтобы достичь этого.

grep -r <text_fo_find> <directory>

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

grep -ir <text_to_find> <directory>
Prash
источник
В моем случае это выглядит как поиск везде, даже если я
укажу
@Pathros Возможно, это связано с включенной рекурсией и указанным каталогом. Иными словами, рекурсия действительно меняет вещи таким образом.
Прифтан
@Pathros Да, и если -в строке поиска есть какие-то s, вы --сначала захотите передать их в grep; в противном случае это может вызвать интересные побочные эффекты!
Прифтан
13

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

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

nitinr708
источник
Это также работает в Git Bash (Windows).
Питер Мортенсен
Но это подразумевает, что каждый файл должен быть найден (без фильтра по имени файла или уровню расширения файла, например .txt). Или есть способ сделать это?
Питер Мортенсен
12

Для поиска строки и вывода только этой строки вместе со строкой поиска:

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;

источник
1
Я вижу только недостаток по сравнению с использованием find … -exec grep 'str' {} \;(если вы должны использовать findвообще).
phk
1
Это ужасно сломалось бы, если какой-либо из файлов, найденных findпробелами, мог привести greppingк неправильным файлам и / или отсутствию нужных файлов. Просто используйте, find ... -exec grep ...если у вас есть необходимость использовать find.. но в этом случае grep -r ...достаточно.
Шаломб
1
Какой смысл использовать цикл по результатам поиска, чтобы затем grep? Это становится излишне сложным.
Федорки 'ТАК прекрати вредить'
12

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

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

ack -i search_string folder_path/*

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

собутыльник
источник
2
Что это добавляет к существующим ответам? Это было предложено более трех лет назад.
Федорки 'ТАК прекрати вредить'
1
@fedorqui 1) нет труб! 2) Используйте регулярные выражения. 3) Получите номера строк, имя файла с относительным путем, выделенный текст и т. Д., Полезные для редактирования после поиска, например, «vim + lineno path / file.cpp» доставит вас прямо к строке, которая вас не интересует. См. Вывод команды «ack include \ | hpp», которая выполняет поиск по ключевым словам «include» или «hpp» в моей папке поиска и подпапках. Надеюсь, суть ясна. Вот пример выходных данных (Невозможно показать выделение ключевых слов простым текстом) process / child.hpp 11: boost / process / child.hpp process / all.hpp 21: #include <boost / process / execute.hpp>
Приятель
12

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

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

Питер М. - выступает за Монику
источник
Рейнджер будет в той же идее
Нилон
11

Команда ниже будет хорошо работать для этого подхода:

find ./ -name "file_pattern_name"  -exec grep -r "pattern" {} \;
Прадип Госвами
источник
2
какой смысл использовать findи тогда grep -r? Они предназначены для одного и того же, так что это избыточно.
Федорки 'ТАК прекрати вредить'
ооо !! исправлено, на самом деле find - это запуск grep для отфильтрованных файлов, но не для всех, спасибо
Pradeep Goswami
2
тем не менее, это не имеет никакого смысла, вы можете фильтровать с find.
Федорки "ТАК прекратить причинять вред"
11

Избегайте хлопот и установите ack-grep. Это устраняет много проблем с разрешениями и цитатами.

apt-get install ack-grep

Затем перейдите в каталог, который вы хотите найти и выполните команду ниже

cd /
ack-grep "find my keyword"
Карима
источник