Я'пытаюсь найти способ просканировать всю мою систему Linux на наличие всех файлов, содержащих определенную строку текста. Чтобы уточнить, я ищу текст внутри файла, а не в имени файла.
Когда я искал, как это сделать, я дважды наткнулся на это решение:
find / -type f -exec grep -H 'text-to-find-here' {} \;
Однако оно не работает. Кажется, что он отображает все файлы в системе.
Близок ли этот способ к правильному? Если нет, то как это сделать? Эта возможность находить текстовые строки в файлах была бы чрезвычайно полезна для некоторых проектов по программированию, которыми я занимаюсь.
Сделайте следующее:
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
. Например, это исключит каталоги 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'
В корневом каталоге.
Вы также можете использовать регулярные выражения, указывать тип файла и т.д.
ОБНОВЛЕНИЕ
Я только что обнаружил The Silver Searcher, который похож на 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 "Строка для поиска" /path/to/directory/or/file. -r: рекурсивный поиск n: номер строки будет показан для совпадений
Во-первых, я полагаю, что вы использовали -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$
Даже если вы не используете регистр, например, "text" против "TEXT", вы можете использовать переключатель -i
, чтобы игнорировать регистр. Более подробную информацию вы можете прочитать здесь.
Надеюсь, это вам поможет.
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
или подобных, поскольку он построен на основе движка regex Rust, который использует конечные автоматы, SIMD и агрессивные оптимизации литералов для очень быстрого поиска.
Он поддерживает шаблоны игнорирования, указанные в файлах .gitignore
, поэтому один путь к файлу может быть сопоставлен с несколькими шаблонами glob одновременно.
Вы можете использовать такие общие параметры, как:
-i
- Нечувствительный поиск.-I
- Игнорировать бинарные файлы.-w
- Поиск целых слов (противоположно частичному подбору слов).-n
- Показать строку совпадения.-C
/--context
(например, -C5
) - Увеличивает контекст, так что вы видите окружающий код.--color=auto
- Пометить совпадающий текст.-H
- Отображает имя файла, в котором найден текст.-c
- Отображает количество совпадающих строк. Может комбинироваться с -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
- выводить только строку, в которой найдено совпадение (не имя файла)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
в конце команды, чтобы избежать множества 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", в зависимости от того, где вы хотите искать....
Существует новая утилита под названием The Silversearcher.
sudo apt install silversearcher-ag
Она тесно сотрудничает с Git и другими VCS. Поэтому вы не получите ничего в .git или другом каталоге.
Вы можете просто использовать
ag "Search query"
И он выполнит задачу за вас!
Используйте команду pwd для поиска из любого каталога, где вы находитесь, рекурсией вниз
grep -rnw `pwd` -e "pattern"
Обновление
В зависимости от версии грэп вы используете, вы можете опустить дуо
. На новых версиях.
, кажется, по умолчанию для grep, если каталог не указывается
таким образом:
команда grep -rnw -е "по схеме"
в
или
грэп -rnw-то "узор"
в
будет делать то же самое, что и выше!
команда grep
может использоваться, даже если мы'повторно не ищу строку.
Просто работает,
grep -RIl "" .
выведет путь к все текстовые файлы, т. е. те, которые содержат только печатные символы.
Здесь представлены несколько список команд, которые можно использовать для поиска файлов.
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
find /path -type f -exec grep -l "string" {} \;
Объяснение с комментариями
найти команду, которая позволяет найти файлы и другие объекты, такие как каталоги и ссылки в подкаталогах заданного пути. Если вы Don'т указать маску, что filesnames должны встретиться, он перечисляет все объекты каталога.
-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
Серебряный поисковик-это потрясающий инструмент, но ripgrep может быть даже лучше.
Она работает на Linux, Mac и Windows, и была написана на Хакер Новости пару месяцев назад (это ссылка на Андрей галантный'с блога, который имеет GitHub ссылке):
Попробуйте:
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
немного, чтобы дать больше информации в выходной, например, чтобы получить номер строки в файле, где текст может быть сделано следующим образом:
find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"
И если у вас есть идея, какой тип файла вы можете сузить область поиска с помощью указания расширений типа файла для поиска в этом случае.ПАили
.DFM-файлов`:
find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext"
Краткое описание варианта:
.
В найти
указывается от текущего каталога.-имя в
"*.*
&я : для всех файлов
( -именем "*.пас в
" -О-именем "*.ДФМ в
" ) : только *.ПА
или *.файлы ПДФ, или указано с
-о `-тип F
указывает, что вы ищете файлы-print0 команды
и - нуль
с другой стороны |
(трубы) являются критическими, передавая имя из найти
в команда grep
вкладывается в размер
, что позволяет передачу файлов с пробелами в именах файлов, позволяя grep для лечения путь и имя файла в виде одной строки, а не разбить его на участки.Простой найти
можете работать удобно. псевдоним его в ваш~/.файл bashrc`:
alias ffind find / -type f | xargs grep
Запуск нового терминала и вопрос:
ffind 'text-to-find-here'