
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 grep
logischer Operatoren.
Die Verwendung mehrerer
-e
Optionen entspricht allem, was einem der Muster entspricht, und gibt demODERBetrieb.Beispiel:
grep -e pattern1 -e pattern2 filename
In erweiterten regulären Ausdrücken (
grep -E
) können Sie|
mehrere Muster mit demODERBetrieb.Beispiel:
grep -E 'pattern1|pattern2' filename
grep -v
kann simulieren dieNICHTBetrieb.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 awk
kö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, grep
um 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 -E
Option zum ODER-Verknüpfen und -v
zum Negieren kombinieren.
Ihr konkretes Beispiel ist ziemlich fies und würde wahrscheinlich von einem leistungsfähigeren Dienstprogramm profitieren (siehe die Antwort von @muru).