5

Я использую команду, подобную этой, чтобы найти файлы со словом «термин» в них:

grep -l term *

Но теперь я хочу найти файлы, в которых есть два разных слова (назовем их termA и termB) - не обязательно в одной строке. Я хочу найти файлы с обоими терминами, а не только файлы с любым термином.

Теперь я мог бы написать для этого громоздкий сценарий bash, но есть ли у grep, egrep, awk, sed или что-нибудь еще инструмент, который может мне помочь?

Заранее спасибо.

3 ответа3

4

Если ваши файлы не содержат нулевых байтов

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

grep -Plz "termA.*termB|termB.*termA" *

Как это устроено:

  • Совместимые с Perl регулярные выражения termA.*termB и termB.*termA ищут строки, в которых есть оба термина.

  • Комбинированный PCRE termA.*termB|termB.*termA соответствует всем строкам, содержащим оба термина.

  • Наконец, ключ -z делает строки данных заканчивающимися нулевыми байтами, а не символами новой строки.

Кстати, нет необходимости использовать -P . Если вы предпочитаете продолжать использовать POSIX Basic Regular Expressions, синтаксис будет аналогичным:

grep -lz "termA.*termB\|termB.*termA" *

Если ваши файлы содержат нулевые байты

В этом случае вам понадобятся вспомогательные инструменты:

(grep -l termA * ; grep -l termB *) | sort | uniq -d

Как это устроено:

  • grep -l termA * ; grep -l termB * отображает все файлы, содержащие любой из терминов. Файлы, содержащие оба термина, будут отображены дважды.

  • sort сортирует вывод

  • uniq -d отображает только дубликаты строк (обязательные для сортировки строки).

3

Вы можете использовать опции -e или -f для поиска нескольких выражений (из man grep):

    -e PATTERN, --regexp=PATTERN
          Use  PATTERN  as  the  pattern.   This  can  be  used to specify
          multiple search patterns, or to protect a pattern beginning with
          a hyphen (-).  (-e is specified by POSIX.)

   -f FILE, --file=FILE
          Obtain  patterns  from  FILE,  one  per  line.   The  empty file
          contains zero patterns, and therefore matches nothing.   (-f  is
          specified by POSIX.)

Таким образом, вы будете использовать это как:

$ grep -e termA -e termB *
1

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

    grep 'termA\|termB' /i/am/a/path

вам нужно использовать escape-символ '\' перед каждым '|' но я уверен, что вы можете использовать столько строк поиска, сколько захотите

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .