grep с логическими операторами

grep с логическими операторами

Есть ли утилита типа grep, которая позволит мне выполнять поиск grep с логическими операторами. Я хочу иметь возможность свободно вкладывать и комбинировать логические конструкции. Например, должно быть возможно что-то вроде этого:

grep (term1 && term2) || (term1 && (term3 xor term4)) *

Я понимаю, что это можно сделать с помощью vanilla grep и дополнительных скриптов bash, но моя цель — избежать необходимости делать это.

решение1

Существует множество способов использования grepлогических операторов.

  1. Использование нескольких -eвариантов соответствует всему, что соответствует любому из шаблонов, даваяИЛИоперация.

    Пример:grep -e pattern1 -e pattern2 filename

  2. В расширенных регулярных выражениях ( grep -E) можно использовать |для объединения нескольких шаблонов с помощьюИЛИоперация.

    Пример: grep -E 'pattern1|pattern2' filename

  3. grep -vможет имитироватьНЕТоперация.

  4. Здесь нетИоператор в grep, но вы можете смоделировать методом перебораИиспользуя несколько шаблонов с |.

    Пример :grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename

    Приведенный выше пример будет соответствовать всем строкам, которые содержат оба шаблон1ишаблон2в любом порядке. Это становится очень некрасивым, если нужно объединить больше шаблонов.

решение2

С awk, как и с perl, вам придется заключать термины в //, но это можно сделать:

awk '(/term1/ && /term2/) || (/term1/ && xor(/term3/, /term4/))' 

Обратите внимание, что xor()нестандартное расширение GNU является битовым xor, а не логическим. Здесь это нормально, поскольку они /regex/всегда возвращают только 0 или 1.

С другими awkвы можете определить логическую xor()функцию:

function xor(a, b) {
  return (a || b && ! (a && b))
}

Или

function xor(a, b) {
  return ((a && !b) || (b && !a))
}

решение3

Вы можете использовать Perl:

perl -wne 'print if (/term1/ && /term2/) || (/term1/ && (/term3/ xor /term4/))'

Гдепереключателиследующие:

-w turns on warnings
-n runs perl against each line of input (looping)
-e executes perl passed in the command line

решение4

Я использую цепочку grepкоманд для достижения логического И:

grep expr1 filename | grep expr2

Я считаю, что это довольно просто, Unix-подобно и элегантно.


Затем вы можете объединить (как подробно объяснил @Tushi) с -Eопцией для ИЛИ и -vдля отрицания.

Ваш конкретный пример довольно неприятен и, вероятно, выиграл бы от использования более мощной утилиты (см. ответ @muru).

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