Versuchen Sie nicht, grep dafür zu verwenden, sondern verwenden Sie stattdessen awk. Um 2 reguläre Ausdrücke R1 und R2 in grep abzugleichen, würde man denken, es wäre:
grep 'R1.*R2|R2.*R1'
während in awk wäre es:
awk '/R1/ && /R2/'
aber was ist, wenn R2
sich mit oder eine Teilmenge von überschneidet R1
? Dieser grep-Befehl würde einfach nicht funktionieren, während der awk-Befehl dies tun würde. Können sagen , Sie Linien finden möchten , die enthalten the
und heat
:
$ echo 'theatre' | grep 'the.*heat|heat.*the'
$ echo 'theatre' | awk '/the/ && /heat/'
theatre
Dafür müssten Sie 2 Greps und eine Pipe verwenden:
$ echo 'theatre' | grep 'the' | grep 'heat'
theatre
und natürlich, wenn Sie tatsächlich verlangt hätten, dass sie getrennt sind, können Sie in awk immer den gleichen regulären Ausdruck schreiben, den Sie in grep verwendet haben, und es gibt alternative awk-Lösungen, bei denen die regulären Ausdrücke nicht in jeder möglichen Reihenfolge wiederholt werden.
Abgesehen davon, was wäre, wenn Sie Ihre Lösung auf 3 reguläre Ausdrücke R1, R2 und R3 erweitern möchten. In grep wäre das eine dieser schlechten Entscheidungen:
grep 'R1.*R2.*R3|R1.*R3.*R2|R2.*R1.*R3|R2.*R3.*R1|R3.*R1.*R2|R3.*R2.*R1' file
grep R1 file | grep R2 | grep R3
während in awk wäre es das prägnante, offensichtliche, einfache, effiziente:
awk '/R1/ && /R2/ && /R3/'
Was wäre, wenn Sie tatsächlich die Literalzeichenfolgen S1 und S2 anstelle der regulären Ausdrücke R1 und R2 abgleichen möchten? Sie können das einfach nicht in einem Aufruf von grep tun. Sie müssen entweder Code schreiben, um alle RE-Metachare zu umgehen, bevor Sie grep aufrufen:
S1=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< 'R1')
S2=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< 'R2')
grep 'S1.*S2|S2.*S1'
oder wieder 2 greps und eine Pfeife verwenden:
grep -F 'S1' file | grep -F 'S2'
Dies sind wiederum schlechte Entscheidungen, während Sie mit awk einfach einen Zeichenfolgenoperator anstelle des regulären Ausdrucksoperators verwenden:
awk 'index($0,S1) && index($0.S2)'
Was wäre, wenn Sie 2 reguläre Ausdrücke in einem Absatz und nicht in einer Zeile abgleichen möchten? Kann nicht in grep gemacht werden, trivial in awk:
awk -v RS='' '/R1/ && /R2/'
Wie wäre es mit einer ganzen Datei? Wiederum kann es in awp nicht in grep und trivial gemacht werden (diesmal verwende ich GNU awk für Multi-Char-RS aus Gründen der Übersichtlichkeit, aber es ist nicht viel mehr Code in einem awk, oder Sie können ein Control-Char auswählen, von dem Sie wissen, dass es nicht funktioniert in der Eingabe sein, damit der RS dasselbe tut):
awk -v RS='^$' '/R1/ && /R2/'
Wenn Sie also mehrere reguläre Ausdrücke oder Zeichenfolgen in einer Zeile, einem Absatz oder einer Datei suchen möchten, verwenden Sie nicht grep, sondern awk.