grep mit logischen Operatoren

grep mit logischen Operatoren

Gibt es ein grep-ähnliches Dienstprogramm, mit dem ich grep-Suchen mit logischen Operatoren durchführen kann? Ich möchte die logischen Konstrukte frei verschachteln und kombinieren können. So etwas sollte beispielsweise möglich sein:

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

Mir ist klar, dass dies mit Vanilla Grep und zusätzlichen Bash-Skripten möglich ist, aber mein Ziel besteht darin, dies zu vermeiden.

Antwort1

Es gibt viele Möglichkeiten zur Verwendung greplogischer Operatoren.

  1. Die Verwendung mehrerer -eOptionen entspricht allem, was einem der Muster entspricht, und gibt demODERBetrieb.

    Beispiel:grep -e pattern1 -e pattern2 filename

  2. In erweiterten regulären Ausdrücken ( grep -E) können Sie |mehrere Muster mit demODERBetrieb.

    Beispiel: grep -E 'pattern1|pattern2' filename

  3. grep -vkann simulieren dieNICHTBetrieb.

  4. Es gibt keinUNDOperator in grep, aber Sie können mit Brute-Force simulierenUNDdurch die Verwendung mehrerer Muster mit |.

    Beispiel :grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename

    Das obige Beispiel wird alle Zeilen abgleichen, die beides enthalten Muster1UndMuster2in beliebiger Reihenfolge. Dies wird sehr hässlich, wenn mehrere Muster kombiniert werden müssen.

Antwort2

Bei müssen Sie awk, wie bei , Begriffe in einschließen , aber es ist möglich:perl//

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

Beachten Sie, dass xor()es sich bei einer nicht standardmäßigen GNU-Erweiterung um eine bitweise Erweiterung handelt xor, nicht um eine logische. Das ist hier in Ordnung, da diese /regex/immer nur 0 oder 1 zurückgeben.

Mit anderen awkkönnen Sie eine logische Funktion xor()als Funktion definieren:

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

Oder

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

Antwort3

Sie könnten Perl verwenden:

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

Bei dem dieSchaltersind wie folgt:

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

Antwort4

Ich verwende die Befehlsverkettung, grepum ein logisches UND zu erreichen:

grep expr1 filename | grep expr2

Ich glaube, es ist ziemlich unkompliziert, Unix-ähnlich und elegant.


Dann können Sie (wie @Tushi ausführlich erklärt hat) mit der -EOption zum ODER-Verknüpfen und -vzum Negieren kombinieren.

Ihr konkretes Beispiel ist ziemlich fies und würde wahrscheinlich von einem leistungsfähigeren Dienstprogramm profitieren (siehe die Antwort von @muru).

verwandte Informationen