Ich würde gerne wissen, ob es eine Möglichkeit gibt, eine Reihe von grep-Anweisungen zu kombinieren, bei denen der Effekt darin besteht, die Ausdrücke „und“ statt „oder“ die übereinstimmenden Ausdrücke zu verwenden.
Demo unten:
./script  
     From one grep statement, I want output like this
a b c
     not like this
a
c
a b
a b c
a b c d
 Hören Sie sich das Skript an.
 #!/bin/bash
 string="a
 b
 c
 d
 a b
 a b c
 a b c d"
 echo -e "\t From one grep statement I want output like this"
 echo "$string" |
 grep a |grep c |grep -v d #Correct output but pipes three grep statements
 echo -e "\n\tNot like this"
 echo "$string" |
 grep -e'a' -e'c' -e-v'd' #One grep statement but matching expressions are "or" versus "and"
 Akzeptierte Antwort:
 Sie können den Filter grep a | grep c | grep -v d zu einem einzigen einfachen grep . Es gibt nur komplizierte und uneffektive Wege. Das Ergebnis hat eine langsame Leistung und die Bedeutung des Ausdrucks ist verschleiert.
Einzelne Befehlskombination der drei Greps
 Wenn Sie nur einen einzelnen Befehl ausführen möchten, können Sie awk verwenden das auch mit regulären Ausdrücken funktioniert und diese mit logischen Operatoren kombinieren kann. Hier ist das Äquivalent Ihres Filters:
awk '/a/ && /c/ && $0 !~ /d/'
 Ich denke, in den meisten Fällen gibt es keinen Grund, eine Pipe zu einem einzelnen Befehl zu vereinfachen, außer wenn die Kombination zu einem relativ einfachen grep-Ausdruck führt, der schneller sein könnte (siehe Ergebnisse unten).
Unix-ähnliche Systeme sind darauf ausgelegt, Pipes zu verwenden und verschiedene Dienstprogramme miteinander zu verbinden. Die Rohrkommunikation ist zwar nicht die effektivste, aber in den meisten Fällen ausreichend. Da heutzutage die meisten neuen Computer mehrere CPU-Kerne haben, können Sie die CPU-Parallelisierung „natürlich“ nutzen, indem Sie einfach eine Pipe verwenden!
 Ihr ursprünglicher Filter funktioniert sehr gut und ich denke, dass in vielen Fällen der awk Lösung wäre selbst auf einem einzelnen Kern etwas langsamer.
Leistungsvergleich
 Mit einem einfachen Programm habe ich aus den Zeichen a eine zufällige Testdatei mit 200 000 000 Zeilen zu je 4 Zeichen als Zufallskombination generiert , b , c und d . Die Datei hat 1 GB. Während der Tests wurde es vollständig in den Cache geladen, sodass keine Festplattenoperationen die Leistungsmessung beeinflussten. Die Tests wurden auf Intel Dual Core ausgeführt.
Single grep
$ time ( grep -E '^[^d]*a[^d]*c[^d]*$|^[^d]*c[^d]*a[^d]*$' testfile >/dev/null )
real    3m2.752s
user    3m2.411s
sys 0m0.252s
 Single awk
$ time ( awk '/a/ && /c/ && $0 !~ /d/' testfile >/dev/null )
real    0m54.088s
user    0m53.755s
sys 0m0.304s
 Die ursprünglichen drei Greps wurden geleitet
$ time ( grep a testfile | grep c | grep -v d >/dev/null )
real    0m28.794s
user    0m52.715s
sys 0m1.072s
 Hybrid – positive Greps kombiniert, negative Pipe
$ time ( grep -E 'a.*c|c.*a' testfile | grep -v d >/dev/null )
real    0m15.838s
user    0m24.998s
sys 0m0.676s
 
 Hier sehen Sie, dass das einzelne grep ist aufgrund des komplexen Ausdrucks sehr langsam. Die ursprüngliche Pipe von drei greps ist wegen einer guten Parallelisierung ziemlich schnell. Ohne Parallelisierung – auf einem einzelnen Kern – läuft die ursprüngliche Pipe nur geringfügig schneller als awk der als einzelner Prozess nicht parallelisiert wird. Awk und grep verwenden wahrscheinlich denselben Code für reguläre Ausdrücke und die Logik der beiden Lösungen ist ähnlich.
 Der klare Gewinner ist die Hybrierung, die zwei positive Greps kombiniert und das negative in der Pfeife lässt. Es scheint, dass der reguläre Ausdruck mit | hat keine Leistungseinbußen.