Grep 'OR' Regex Problem

65

Ich versuche, grep mit einem regulären Ausdruck zu verwenden, um Zeilen in einer Datei zu finden, die mit 1 von 2 möglichen Zeichenfolgen übereinstimmen. Hier ist mein Grep:

$ grep "^ID.*(ETS|FBS)" my_file.txt

Das obige grep gibt keine Ergebnisse zurück. Wenn ich jedoch eine der folgenden Aktionen ausführe:

$ grep "^ID.*ETS" my_file.txt  

oder

$ grep "^ID.*FBS" my_file.txt  

Ich stimme mit bestimmten Zeilen überein. Warum stimmt mein OP-Regex nicht überein? Vielen Dank im Voraus für die Hilfe!

dr.bunsen
quelle

Antworten:

94

Bei normalen regex, die Charaktere (, |und )Notwendigkeit zu entkommen werden. Also solltest du verwenden

$ grep "^ID.*\(ETS\|FBS\)" my_file.txt

Sie brauchen die Escape- Zeichen nicht, wenn Sie die erweiterte-E Option regex ( ) verwenden. Siehe man grepAbschnitt " Basic vs Extended Regular Expressions".

rozcietrzewiacz
quelle
10
Sie können auch egrepanstelle von verwenden grep -E.
Riccardo Murri
2
@RiccardoMurri Die Antwort von Michal besagt, dass egrep (und fgrep) veraltet sind (obwohl sie möglicherweise noch funktionieren).
Timo
27

Wenn Sie mehrere Zweige (das |As or) verwenden möchten , ist es aus Kompatibilitätsgründen besser, explizit zu sagen, dass Sie "modernes RE", auch bekannt als, verwenden möchten. EHE.

Verwenden Sie dazu grep -E :

grep -E "^ID.*(ETS|FBS)" my_file.txt

Um mehr über RE, ERE und die ganze "moderne" ER-Geschichte zu erfahren, siehe man 7 regex.

Alternativ können Sie egrepstatt verwenden grep, aber wie Sie lesen können man grep:

egrep ist dasselbe wie grep -E. fgrep ist dasselbe wie grep -F

(...)

Direkter Aufruf als egrep oder fgrep ist veraltet

Michał Šrajer
quelle
Während der direkte Aufruf von egrep veraltet ist, funktioniert er in den meisten * nix-Varianten.
Mark D