Ich brauche einen Regex für einen einzigen Durchgang für Unix-Grep, der beispielsweise Alpha enthält, aber keine Beta enthält.
grep 'alpha' <> | grep -v 'beta'
^((?!beta).)*alpha((?!beta).)*$
würde den Trick machen, denke ich.
Die anderen Antworten hier zeigen einige Möglichkeiten, wie Sie verschiedene Regex-Varianten dazu verzerren können, obwohl sich meiner Meinung nach herausstellt, dass die Antwort im Allgemeinen lautet: "Tun Sie das nicht". Solche regulären Ausdrücke sind viel schwieriger zu lesen und wahrscheinlich langsamer auszuführen, als nur zwei reguläre Ausdrücke mit der booleschen Logik der verwendeten Sprache zu kombinieren. Wenn Sie den Befehl grep
an einer Unix-Shell-Eingabeaufforderung verwenden, leiten Sie einfach die Ergebnisse von einem an den anderen weiter:
grep "alpha" | grep -v "beta"
Ich verwende diese Art von Konstrukt ständig, um übermäßige Ergebnisse von grep
herauszuarbeiten. Wenn Sie eine Vorstellung davon haben, welche Ergebnismenge kleiner sein wird, setzen Sie diese zuerst in die Pipeline, um die beste Leistung zu erzielen, da der zweite Befehl nur die Ausgabe der ersten und nicht die gesamte Eingabe verarbeiten muss.
Nun, da wir alle Antworten veröffentlichen, ist es in awk ;-)
awk '/x/ && !/y/' infile
Ich hoffe das hilft.
Ich bin mir ziemlich sicher, dass dies mit echten regulären Ausdrücken nicht möglich ist. Das [^y]*x[^y]*
-Beispiel würde mit yxy übereinstimmen, da das * keine oder mehr Nicht-y-Übereinstimmungen zulässt.
BEARBEITEN:
Eigentlich scheint das zu funktionieren: ^[^y]*x[^y]*$
. Im Grunde bedeutet dies "jede Zeile, die mit null oder mehr Nicht-y-Zeichen beginnt, dann ein x hat und dann mit null oder mehr Nicht-y-Zeichen endet".
Versuchen Sie es mit dem Ausschlussoperator: [^y]*x[^y]*