grep файлы с шаблоном A, но исключить файлы с шаблоном B

grep файлы с шаблоном A, но исключить файлы с шаблоном B

Я хочу выполнить grep для файлов, содержащих шаблон A (iwant), но я хочу исключить файлы, содержащие шаблон B (idontwant).

Пример:

read -p "...what are you looking for: " iwant
read -p "...what should not be included: " idontwant

iwant="blue car" 
idontwant="red car"

Предположим, у меня есть следующие файлы:

-rw-rw-r--.  1 terpentin terpentin  45 Jun  8 16:04 blue.car
-rw-rw-r--.  1 terpentin terpentin  44 Jun  8 16:05 mixed.car
-rw-rw-r--.  1 terpentin terpentin  40 Jun  8 16:04 red.car
find . -type f -print -exec cat {} \;

./mixed.car
blue car
red car
blue car

./red.car
red car
red car
red car

./blue.car
blue car
blue car
blue car

Как можно получить в результате только файл «./blue.car»?

Исходный контент включает сотни длинных текстовых файлов, поэтому важно обеспечить максимальную эффективность использования ресурсов.

решение1

Использовать

find . -type f ! -exec grep -q "$idontwant" {} ';' -exec grep -q "$iwant" {} ';' -print

или

find . -type f -exec grep -q "$iwant" {} ';' ! -exec grep -q "$idontwant" {} ';' -print
  • Термины (иногда называемые «предикатами») в find команде характеризуются кактесты(например,  -type f) идействия(например,  -printи  -delete). Из страницы руководства может быть трудно понять, что -execявляется и действиеи а тест. Так же, как и
    найти . -тип f -mtime -30 -имя '*.txt' -читаемый -размер +5тест 6 тест 7 тест 8
    последовательно сужает поиск до файлов, которые соответствуют всем критериям (удовлетворяют всем указанным тестам), поэтому
    найти . -execкоманда 1{} ';' -execкоманда 2{} ';' -execкоманда 3{} ';' …
    находит файлы, для которых все команды выполнены успешно.
  • Любой findтест можно отменить (инвертировать), поставив перед ним !. Так find . ! -type dнаходятся простые файлы, символические ссылки, именованные каналы, сокеты и файлы устройств — все, кроме каталогов.
  • Обратите внимание, что это ! -exec grep …не эквивалентно -exec grep -v …-exec grep -v …будут найдены файлы, в которых есть хотя бы одна несоответствующая строка.  ! -exec grep …будут найдены файлы, в которыхнетлинии совпадают.
  • Параметр -qto grepофициально является синонимом --quiet, но он также означаетбыстрый. Он не выводит никаких данных (за исключением, возможно, сообщений об ошибках, если применимо), но также он завершает работу, как только находит совпадение — он не читает каждый файл до конца, чтобы найтикаждыйсовпадение. (Конечно, если файл не содержит совпадений, то grepдля определения этого необходимо прочитать его полностью.)
  • Так (TL;DR) команды находят файлы, для которых
    grep -q "$iwant"     файл
    преуспевает и
    grep -q "$idontwant"файл
    не выполняется (потому что мы добавили перед ним !).
  • Две команды функционально эквивалентны, но могут иметь разную производительность (т. е. могут занимать разное время для выполнения). Если только несколько файлов содержат строки поиска,
    найти . -тип f -exec grep -q "$iwant" {} ';' ! -exec grep -q "$idontwant" {} ';' –print
    будет быстрее, потому что grep "$iwant"устранит большинство файлов. Если многие файлы содержат обе строки, то
    найти . -тип f ! -exec grep -q "$idontwant" {} ';' -exec grep -q "$iwant" {} ';' –print
    будет быстрее, так как ! grep "$idontwant"будет удалена большая часть файлов.

решение2

С помощью этой команды GNU grepмы можем выполнить извлечение имени файла, разумно выбрав параметры регулярных выражений и grep:

$ grep -lzPsr '(?s:(?=.*blue)(?!.*red))' .

Мы запускаем grep в режиме slurp (-z), в котором весь файл рассматривается как одна большая строка.

Параметр -l выведет список имен файлов, соответствующих регулярному выражению.

Параметр -r будет рекурсивно выполняться для всех файлов в текущем каталоге и ниже.

Параметр -s отключит grep и не будет выдавать никаких предупреждений.

Регулярное выражение будет искать наличие синего цвета и отсутствие красного цвета в файле, чтобы ответить «да».

Параметр -P вызывает механизм регулярных выражений Perl в grep, что позволяет нам воспользоваться преимуществами регулярных выражений pcre.

Связанный контент