Найти файлы, содержащие заданный текст


153

В bash я хочу вернуть имя файла (и путь к файлу) для каждого файла типа, .php|.html|.jsсодержащего строку без учета регистра"document.cookie" | "setcookie"

Как бы я это сделал?


4
Вы рассматривали только использование grep? cyberciti.biz/faq/grep-in-bash
Терранс

Этот заголовок вводит в заблуждение. «найти-файлы-содержащие-данный-текст»
Джош C

Ответы:


212
egrep -ir --include=*.{php,html,js} "(document.cookie|setcookie)" .

rФлаг означает рекурсивный поиск (поиск подкаталоги). iФлаг означает чувствителен к регистру.

Если вы просто хотите, чтобы имена файлов добавлялись l(строчные буквы L):

egrep -lir --include=*.{php,html,js} "(document.cookie|setcookie)" .

это, кажется, не работает для меня (по крайней мере, на Mac) .... просто зависает ... egrep -lir --include = * "repo" egrep: warning: рекурсивный поиск stdin
Дин Хиллер

13
Вы забыли добавить путь для поиска. Путь "." в приведенном выше примере. В вашем случае скрипт ожидает ввода для поиска по стандартному вводу. Попробуйте: egrep -lir --include = * "repo" / (или любой другой путь)
LodeRunner

1
grep -E ... >egrep ...
Аман

Я получил ошибку grep: (error|fail): No such file or directoryна Ubuntu Desktop 16; какие-нибудь намеки?
Nam G VU

Чтобы заставить это работать, мне пришлось пропустить * с \. так что у меня--include=\*.{php,html,js}
Мехрад Махмудян

53

Попробуйте что-то вроде grep -r -n -i --include="*.html *.php *.js" searchstrinhere .

-iделает его случай insensitlve

.на концах означает , что вы хотите , чтобы начать с текущего каталога, это может быть заменен любой каталог.

что -rозначает сделать это рекурсивно, прямо вниз по дереву каталогов

-nпечатает номер строки для матчей.

--includeпозволяет добавлять имена файлов, расширений. Подстановочные знаки принимаются

Для получения дополнительной информации см .: http://www.gnu.org/software/grep/


4
Или, возможно, используйте -lопцию (просто -n
напишите

15

findих и grepдля строки

Это найдет все файлы ваших 3-х типов в / start / path и grep для регулярного выражения '(document\.cookie|setcookie)'. Разделите 2 строки с помощью обратной косой черты только для удобства чтения ...

find /starting/path -type f -name "*.php" -o -name "*.html" -o -name "*.js" | \
 xargs egrep -i '(document\.cookie|setcookie)'

1
Вроде универсального использования find, но, на мой взгляд, лучше использовать-exec grep -l 'sth' {} \;
NGix

Спасибо @Michael Berkowski. Этот способ быстрее всего более 5 или 8 раз # egrep -ir --include=file.foo "(foo|bar)" /dirна ~ 500Gb весовой директории.
Qh0stM4N

9

Похоже, идеальная работа для grepили, возможно, ACK

Или это замечательная конструкция:

find . -type f \( -name *.php -o -name *.html -o -name *.js \) -exec grep "document.cookie\|setcookie" /dev/null {} \;

+1 Использование -exec grep...лучше, чем мой xargsметод, потому что он не захлебнется пробелами в именах файлов.
Майкл Берковски

@MichaelBerkowski: Вы можете использовать его как это дело с пробелами в именах файлов: find . -type f -print0 | xargs -0 -I {} grep "search_string" {}. Конечно, могут быть добавлены и другие опции.
Паскаль

4
find . -type f -name '*php' -o -name '*js' -o -name '*html' |\
xargs grep -liE 'document\.cookie|setcookie'

3

Просто чтобы включить еще одну альтернативу, вы также можете использовать это:

find "/starting/path" -type f -regextype posix-extended -regex "^.*\.(php|html|js)$" -exec grep -EH '(document\.cookie|setcookie)' {} \;

Куда:

  • -regextype posix-extendedговорит, findкакое регулярное выражение ожидать
  • -regex "^.*\.(php|html|js)$"говорит findсамому регулярному выражению имена файлов должны совпадать
  • -exec grep -EH '(document\.cookie|setcookie)' {} \;указывает findна выполнение команды (с ее параметрами и аргументами), указанной между -execпараметром и \;для каждого файла, который он находит, где {}представляет путь к файлу в этой команде.

    пока

    • Eопция говорит grepиспользовать расширенное регулярное выражение (для поддержки скобок) и ...
    • Hопция говорит grepпечатать пути к файлам до совпадений.

И, учитывая это, если вы хотите только пути к файлам, вы можете использовать:

find "/starting/path" -type f -regextype posix-extended -regex "^.*\.(php|html|js)$" -exec grep -EH '(document\.cookie|setcookie)' {} \; | sed -r 's/(^.*):.*$/\1/' | sort -u

куда

  • |[pipe] отправляет вывод findследующей команды после этого (то есть sed, затем sort)
  • rопция говорит sedиспользовать расширенное регулярное выражение.
  • s/HI/BYE/говорит sedзаменить каждое Первое вхождение (в строке) слова "HI" на "BYE" и ...
  • s/(^.*):.*$/\1/говорит ему заменить регулярное выражение (^.*):.*$(имеется в виду группа [материал, заключенный в ()], включающий все [ .*= один или несколько произвольных символов] от начала строки [ ^] до 'первого': ', за которым следует что-нибудь до' конца строка [ $]) первой группой [ \1] замененного регулярного выражения.
  • uговорит сортировать, чтобы удалить дубликаты записей (принимать sort -uкак необязательные).

... далеко от самого элегантного способа. Как я уже сказал, я намерен расширить диапазон возможностей (а также дать более полное объяснение некоторых инструментов, которые вы можете использовать).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.