grep з логічними операторами


19

Чи є утиліта, що нагадує греп, яка дозволить мені робити пошук grep з логічними операторами. Я хочу вміти гніздо і поєднувати логічні побудови вільно. Наприклад, такі речі повинні бути можливими:

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

Я розумію, що це можна зробити за допомогою ванільної грепи та додаткових сценаріїв, але моя мета тут уникнути необхідності цього робити.

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може імітувати операцію NOT .

  5. Немає оператора ANDgrep , але ви можете за допомогою опції симулювати буфери І.-E

    Приклад: grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename

    Наведений вище приклад відповідає всім рядкам, що містять і pattern1, і pattern2 в будь-якому порядку.)


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

grep foo | grep barє більш загальним способом зробити І.
Кенстер

2
+1 для чіткого пояснення того, що немає справжнього оператора "І", і що найкраще, що ми можемо зробити, - це імітувати злом, використовуючи структуру АБО. Звичайно, це стане непростим з більш ніж 3 термінами, але для двох термінів це добре працює.
Eric Hepperle - CodeSlayer2010

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

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.