Как найти все файлы, содержащие определенный текст в Linux?
Я пытаюсь найти способ сканирования всей моей системы Linux для всех файлов, содержащих определенную строку текста. Чтобы уточнить, я ищу текст в файле, а не в имени файла.
Когда я искал, как это сделать, я наткнулся на это решение дважды:
find / -type f -exec grep -H 'text-to-find-here' {} \;
Однако это не сработает. Кажется, он отображает каждый файл в системе.
Это близко к правильному способу сделать это? Если нет, как мне? Эта способность находить текстовые строки в файлах будет чрезвычайно полезна для некоторых проектов программирования, которые я делаю.
Ответы
Ответ 1
Выполните следующие действия:
grep -rnw '/path/to/somewhere/' -e 'pattern'
-
-r
или -r
рекурсивны, -
-n
- номер строки, и -
-w
означает совпадение всего слова. -
-l
(нижний регистр 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
. Например, это исключает dir1/, dir2/dir2 и все из них, соответствующие *.dst/:
grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"
Это очень хорошо для меня, для достижения почти той же цели, что и ваша.
Для получения дополнительных параметров проверьте man grep
.
Ответ 2
Вы можете использовать grep -ilR
:
grep -Ril "text-to-find-here" /
-
i
обозначает случай игнорирования (необязательно в вашем случае).
-
R
означает рекурсивный.
-
l
означает "показать имя файла, а не сам результат".
-
/
означает начало с корня вашей машины.
Ответ 3
Вы можете использовать ack. Это похоже на grep для исходного кода. Вы можете просмотреть всю свою файловую систему.
Просто выполните:
ack 'text-to-find-here'
В корневом каталоге.
Вы также можете использовать регулярные выражения, указать тип файла и т.д.
UPDATE
Я только что обнаружил Silver Searcher, который похож на ack, но на 3-5 раз быстрее, чем он, и даже игнорирует шаблоны из файла .gitignore
.
Ответ 4
Вы можете использовать:
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: номер строки будет показан для совпадений
Ответ 5
Вы можете использовать это:
grep -inr "Text" folder/to/be/searched/
Ответ 6
Список имен файлов, содержащих заданный текст
Прежде всего, я полагаю, вы использовали -H
вместо -l
. Также вы можете попробовать добавить текст внутри кавычек, а затем {} \
.
find / -type f -exec grep -l "text-to-find-here" {} \;
пример
Скажем, вы ищете файлы, содержащие определенный текст "Apache License" внутри вашего каталога. Он отобразит результаты, несколько похожие на ниже (вывод будет отличаться в зависимости от содержимого вашего каталога).
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
чтобы игнорировать регистр. Вы можете прочитать более подробную информацию здесь.
Надеюсь, это вам поможет.
Ответ 7
Вы можете использовать инструмент 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
а именно:
rg "class foo" .
Оформить заказ документов, шагов установки или исходного кода на странице проекта GitHub.
Это намного быстрее, чем любой другой инструмент, такой как GNU/BSD grep
, ucg
, ag
, sift
, ack
, pt
или аналогичный, поскольку он построен поверх механизма регулярных выражений Rust, который использует конечные автоматы, SIMD и агрессивные литералы для быстрого поиска,
Он поддерживает шаблоны игнорирования, указанные в файлах .gitignore
, поэтому один путь к файлу может быть сопоставлен с несколькими шаблонами glob одновременно.
Вы можете использовать общие параметры, такие как:
-
-i
- Нечувствительный поиск. -
-i
- Игнорировать двоичные файлы. -
-w
- поиск целых слов (в -w
от частичного совпадения слов). -
-n
- Покажите линию вашего матча. -
-C
/--Context
(например, -C5
) - Увеличивает контекст, поэтому вы видите окружающий код. -
--Color=auto
- --Color=auto
соответствующий текст. -
-H
- отображает имя файла, в котором найден текст. -
-C
- отображает количество совпадающих строк. Может комбинироваться с -H
.
Ответ 8
Если ваш 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
- выводит только строку, которая соответствует (а не имя файла)
Ответ 9
grep -insr "pattern" *
-
i
: игнорировать различия в случаях как в PATTERN, так и в входных файлах.
-
n
: префикс каждой строки вывода с номером строки 1 в его входном файле.
-
s
: Запретить сообщения об ошибках о несуществующих или нечитаемых файлах.
-
r
: рекурсивно читать все файлы под каждым каталогом.
Ответ 10
Как найти все файлы, содержащие определенный текст в Linux? (...)
Я наткнулся на это решение дважды:
find / -type f -exec grep -H 'text-to-find-Here' {} \;
Если вы используете find, как в вашем примере, лучше добавьте -s
(--no-messages
) в grep
и 2>/dev/null
в конце команды, чтобы избежать большого количества сообщений о grep
разрешений, выданных 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", в зависимости от того, где вы действительно хотите выполнить поиск...
Ответ 11
Там новая утилита под названием Silversearcher
sudo apt install silversearcher-ag
Он тесно сотрудничает с Git и другими VCS. Так что вы ничего не получите в .git или другом каталоге.
Вы можете просто использовать
ag "Search query"
И это сделает задачу за вас!
Ответ 12
Try:
find . -name "*.txt" | xargs grep -i "text_pattern"
Ответ 13
Используйте pwd
для поиска из любого каталога, в котором вы находитесь, рекурсивного вниз
grep -rnw `pwd` -e "pattern"
Обновление
В зависимости от версии grep, которую вы используете, вы можете опустить pwd
. В более новых версиях .
, по-видимому, является аргументом по умолчанию для grep, если каталог не указан
Таким образом:
grep -rnw -e "pattern"
или
grep -rnw "pattern"
будет делать то же, что и выше!
Ответ 14
grep
может использоваться, даже если мы не ищем строку.
Просто работает,
grep -RIl "" .
распечатает путь ко всем текстовым файлам, т.е. содержащим только печатные символы.
Ответ 15
Ниже приведен список команд, которые можно использовать для поиска файла.
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
Ответ 16
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
Ответ 17
Надеюсь, что это поможет...
Разверните бит 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
OR *.dfm
, или указанные с помощью -o
-
-type f
указывает, что вы ищете файлы
-
-print0
и --null
на другой стороне |
(pipe) являются ключевыми, передавая имя файла из find
в grep
, встроенное в xargs
, что позволяет прохождение имен файлов С пробелами в именах файлов, что позволяет grep обрабатывать путь и имя файла как одну строку, а не разбивать его на каждом пространстве.
Ответ 18
Try:
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' {} \;
Ответ 19
Silver Searcher - потрясающий инструмент, но ripgrep может быть еще лучше.
Он работает на Linux, Mac и Windows, и был написан на Hacker News пару месяцев назад (у этого есть ссылка на блог Эндрю Галланта, у которого есть ссылка GitHub):
Ripgrep - новый инструмент поиска в командной строке
Ответ 20
Простой find
может работать удобно. alias это в вашем файле ~/.bashrc
:
alias ffind find / -type f | xargs grep
Запустите новый терминал и выполните выпуск:
ffind 'text-to-find-here'
Ответ 21
Я написал Python script, который делает что-то подобное. Вот как следует использовать этот script.
./sniff.py path pattern_to_search [file_pattern]
Первый аргумент path
- это каталог, в котором мы будем искать рекурсивно. Второй аргумент pattern_to_search
- это регулярное выражение, которое мы хотим найти в файле. Мы используем формат регулярного выражения, определенный в библиотеке Python re
. В этом script символ .
также соответствует новой строке.
Третий аргумент 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
И в voila он генерирует путь к сопоставленным файлам и номер строки, по которой было найдено совпадение. Если было найдено несколько совпадений, то каждый номер строки будет добавлен к имени файла.
Ответ 22
Использование:
grep -c Your_Pattern *
Это сообщит, сколько копий вашего шаблона присутствует в каждом из файлов в текущем каталоге.
Ответ 23
grep - ваш хороший друг, чтобы достичь этого.
grep -r <text_fo_find> <directory>
если вам не нужен случай поиска текста, используйте
grep -ir <text_to_find> <directory>
Ответ 24
Чтобы найти строку и вывести только эту строку со строкой поиска:
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;
Ответ 25
Существует инструмент ack
, который будет делать именно то, что вы ищете.
http://linux.die.net/man/1/ack
ack -i search_string folder_path/*
Вы можете игнорировать -i
для поиска с учетом регистра
Ответ 26
Все предыдущие ответы предлагают grep и find. Но есть и другой способ: использовать Midnight Commander
Это бесплатная утилита (30 лет, проверенная временем), которая работает без графического интерфейса. У этого есть тонны функций, и поиск файлов - только одна из них.
Ответ 27
Меня увлекает то, как простой 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
Работает просто отлично.
Надеюсь, что это поможет!
Ответ 28
Если вы строго хотите использовать 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
, чтобы улучшить или сузить поиск файлов.
Ответ 29
Попробуйте следующее:
find . | xargs grep 'word' -sl
Ответ 30
Вы можете использовать команду ниже, так как вам не требуется имя файла, но вы хотите искать из всех файлов. Вот я беру форму "ТЕКСТ". Все файлы журнала, удостоверяющие, что имя файла не напечатано
grep -e TEXT *.log | cut -d' ' --complement -s -f1
grep с параметром -e довольно быстр по сравнению с другим вариантом, как для соответствия PATTERN