Как найти все файлы, содержащие определенный текст в Linux?
Я пытаюсь найти способ сканировать всю мою систему Linux для всех файлов, содержащих определенную строку текста. Просто чтобы уточнить, я ищу текст в файле, а не в имени файла.
Когда я искал, как это сделать, я дважды сталкивался с этим решением:
find / -type f -exec grep -H 'text-to-find-here' {} \;
Тем не менее, это не работает. Кажется, для отображения каждого файла в системе.
Это близко к правильному способу сделать это? Если нет, то как я должен? Эта возможность находить текстовые строки в файлах была бы чрезвычайно полезна для некоторых программных проектов, которыми я занимаюсь.
56 ответов
Сделайте следующее:
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
,
Ты можешь использовать grep -ilR
:
grep -Ril "text-to-find-here" /
i
означает игнорировать регистр (необязательно в вашем случае).R
обозначает рекурсивный.l
расшифровывается как "показать имя файла, а не сам результат"./
обозначает начало в корне вашей машины.
Вы можете использовать ACK. Это как grep для исходного кода. Вы можете сканировать всю вашу файловую систему с ним.
Просто делать:
ack 'text-to-find-here'
В вашем корневом каталоге.
Вы также можете использовать регулярные выражения, указать тип файла и т. Д.
ОБНОВИТЬ
Я только что обнаружил Серебряный Искатель, который похож на ack, но в 3-5 раз быстрее, чем он, и даже игнорирует шаблоны из .gitignore
файл.
Ты можешь использовать:
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: номер строки будет показан для совпадений
Вы можете использовать это:
grep -inr "Text" folder/to/be/searched/
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
или аналогичный, поскольку он построен на основе движка регулярных выражений Rust, который использует конечные автоматы, SIMD и агрессивные буквальные оптимизации, чтобы сделать поиск очень быстрым.
Он поддерживает шаблоны игнорирования, указанные в .gitignore
файлы, поэтому один путь к файлу может быть сопоставлен с несколькими шаблонами глобуса одновременно.
Вы можете использовать общие параметры, такие как:
-i
- Нечувствительный поиск.-I
- игнорировать двоичные файлы.-w
- Поиск целых слов (в отличие от частичного совпадения слов).-n
- Показать линию вашего матча.-C
/--context
(например-C5
) - Увеличивает контекст, поэтому вы видите окружающий код.--color=auto
- Отметьте соответствующий текст.-H
- Отображает имя файла, где находится текст.-c
- Отображает количество совпадающих линий. Может сочетаться с-H
,
Список имен файлов, содержащих данный текст
Прежде всего, я считаю, что вы использовали -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
переключиться, чтобы игнорировать регистр. Вы можете прочитать более подробную информацию здесь.
Надеюсь, это поможет вам.
Эта команда grep даст вам точный результат при поиске определенного текста в Linux —
grep -inRsH "Text to be searched" /path/to/dir (it can be '.')
i
означает игнорирование различий в регистреR
означает рекурсивный, а также включает символические ссылки. Лучше использовать 'R' вместо 'r'n
означает «будет печатать номер строки».s
означает "подавлять сообщения об ошибках"H
означает «он будет печатать имя файла для каждого совпадения».
Если твой 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
- выводить только строку, которая соответствует (не имя файла)
Есть новая утилита под названием Silversearcher
sudo apt install silversearcher-ag
Он работает в тесном сотрудничестве с Git и другими VCS. Так что вы ничего не получите в .git или другом каталоге.
Вы можете просто использовать
ag -ia "Search query"
И это сделает задачу за вас!
grep -insr "pattern" *
i
: Игнорировать различия регистра как в PATTERN, так и во входных файлах.n
: Префикс каждой строки вывода с номером строки на основе 1 в своем входном файле.s
: Подавлять сообщения об ошибках несуществующих или нечитаемых файлов.r
: Рекурсивно читать все файлы в каждом каталоге.
Как найти все файлы, содержащие определенный текст в 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-подобных платформах. Кстати, команда find часто сочетается с xargs.
Для этой цели существуют более быстрые и простые инструменты - см. Ниже. Лучше их попробовать, если они доступны на вашей платформе, конечно:
Более быстрые и легкие альтернативы
RipGrep - самый быстрый инструмент поиска:
rg 'text-to-find-here' / -l
ag 'text-to-find-here' / -l
ack 'text-to-find-here' / -l
Примечание: вы можете добавить 2>/dev/null
к этим командам, чтобы скрыть много сообщений об ошибках.
Предупреждение: если вы действительно не можете избежать этого, не ищите из '/' (корневого каталога), чтобы избежать длительного и неэффективного поиска! Поэтому в приведенных выше примерах вам лучше заменить ' / ' на имя подкаталога, например, "/home", в зависимости от того, где вы действительно хотите искать...
Использование pwd
искать из любого каталога, в котором вы находитесь, возвращаясь вниз
grep -rnw `pwd` -e "pattern"
Обновление В зависимости от используемой версии grep, вы можете опустить pwd
, На более новых версиях .
похоже на случай по умолчанию для grep, если каталог не задан таким образом:
grep -rnw -e "pattern"
или же
grep -rnw "pattern"
будет делать то же самое, что и выше!
Пытаться:
find . -name "*.txt" | xargs grep -i "text_pattern"
Если вы строго хотите использовать find
затем:
1.Use find
искать файлы,
2. Затем выполнить grep
на всех из них.
Может быть объединен в одну команду, как показано ниже:
find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;
использование
-name Pattern
если хотитеgrep
только определенные файлы:find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;
Это может дать вам силу find
найти файлы. Вы можете играть с ним и использовать различные варианты find
улучшить или сузить поиск файлов.
grep
может использоваться, даже если мы не ищем строку.
Просто работает,
grep -RIl "" .
распечатает путь ко всем текстовым файлам, т. е. содержащим только печатные символы.
Silver Searcher - потрясающий инструмент, но ripgrep может быть даже лучше.
Он работает на Linux, Mac и Windows и был написан на Hacker News пару месяцев назад (здесь есть ссылка на блог Эндрю Галланта, на котором есть ссылка на GitHub):
Есть ack
инструмент, который будет делать именно то, что вы ищете.
http://linux.die.net/man/1/ack
ack -i search_string folder_path/*
Вы можете игнорировать -i
для поиска с учетом регистра
Вот несколько списков команд, которые можно использовать для поиска файла.
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 делает это с 'rl'
grep -rl 'pattern_to_find' /path/where/to/find
-r to find recursively file / directory inside directories..
-l to list files matching the 'pattern'
Используйте '-r' без 'l', чтобы увидеть имена файлов, за которыми следует текст, в котором найден шаблон!
grep -r 'pattern_to_find' /path/where/to/find
Работает просто отлично..
Надеюсь, поможет!
grep "text-to-find-here" file_name
или же
grep "text-to-find-here" directory_path/*
Если вы хотите выполнить поиск в текущем каталоге:
grep "text-to-find-here" *
Если вы находитесь в репозитории git, вы можете использовать:
git grep something
Надеюсь, это поможет...
Расширяя 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"
Краткое объяснение вариантов:
.
вfind
указывает из текущего каталога.-name
"*.*
": для всех файлов (-name"*.pas
"-o -name"*.dfm
"): Только*.pas
ИЛИ ЖЕ*.dfm
файлы ИЛИ, указанные с помощью-o
-type f
указывает, что вы ищете файлы-print0
а также--null
на другой стороне|
(труба) являются решающими, передавая имя файла изfind
кgrep
встроен вxargs
, позволяя передавать имена файлов с пробелами в именах файлов, позволяя grep обрабатывать путь и имя файла как одну строку, а не разбивать их на каждый пробел.
Просто find
может работать удобно. псевдоним это в вашем ~/.bashrc
файл:
alias ffind find / -type f | xargs grep
Запустите новый терминал и выполните команду:
ffind 'text-to-find-here'
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
Пытаться:
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 твой хороший друг, чтобы достичь этого.
grep -r <text_fo_find> <directory>
если вам не важен текст, который нужно найти, используйте
grep -ir <text_to_find> <directory>
Чтобы найти строку и вывести только эту строку со строкой поиска:
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;
Я написал скрипт 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
И вуаля, он генерирует путь сопоставленных файлов и номер строки, по которой совпадение было найдено. Если найдено более одного совпадения, то каждый номер строки будет добавлен к имени файла.