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


19

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

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

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

grep 

Ответы:


12

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

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

28

Есть много способов использования grepс логическими операторами.

  1. Используется \|для разделения нескольких шаблонов для условия ИЛИ .

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

  2. Используйте -Eопцию для отправки нескольких шаблонов для условия ИЛИ .

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

  3. Использование одного -eсоответствует только одному шаблону, но использование нескольких -eпараметров соответствует более чем одному шаблону.

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

  4. grep -vможет имитировать операцию НЕ .

  5. Там нет оператора ANDgrep , но вы можете имитировать грубой силой AND , используя -Eопцию.

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

    Приведенный выше пример будет соответствовать всем строкам , которые содержат и образец pattern1 и pattern2 в любом порядке.)


1
-Eне совсем эквивалентно &&из-за того, что он чувствителен к порядку
iruvar

grep foo | grep barэто более общий способ сделать AND.
Кенстер

2
+1 за четкое объяснение того, что нет реального оператора «И», и что лучшее, что мы можем сделать, - это симулировать взлом с помощью структуры ИЛИ. Это, конечно, будет громоздким с более чем 3 терминами, но для двух терминов это работает хорошо.
Эрик Хепперле - CodeSlayer2010

grep -c -e MATCH1 -e MATCH2 отлично подходит, если вас интересует количество имен файлов.
Андрей

4

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

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

0
sed '/term1/!d;/term2/b' -e '/term3/!d;/term4/d' *

Я верю, что это завершает то, что вы пытаетесь сделать. Он dвыводит из вывода любую строку, которая не совпадает term1, bиз сценария (и, таким образом, автоматически печатается) выходит любая строка, которая остается и совпадает term2, а для строк, которые остаются, удаляет любую, которая не совпадает , и строку, term3которая совпадает. term4,

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


0

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

grep expr1 filename | grep expr2

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


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

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

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