Problem wyrażenia regularnego Grep „OR”

65

Próbuję użyć grep z wyrażeniem regularnym, aby znaleźć wiersze w pliku, które pasują do 1 z 2 możliwych ciągów. Oto mój grep:

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

Powyższy grep nie zwraca żadnych wyników. Jeśli jednak wykonam:

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

lub

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

Dopasowuję określone linie. Dlaczego moje wyrażenie regularne OR nie pasuje? Z góry dziękuję za pomoc!

dr.Bunsen
źródło

Odpowiedzi:

94

Przy normalnym regex, bohaterów (, |a )potrzebą być uciekł. Więc powinieneś użyć

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

Nie potrzebujesz ucieczek, gdy używasz opcji Extended regex ( -E). Patrz man grepsekcja „ Basic vs Extended Regular Expressions”.

rozcietrzewiacz
źródło
10
Możesz także użyć egrepzamiast grep -E.
Riccardo Murri,
2
@RiccardoMurri Odpowiedź Michała stwierdza, że ​​egrep (i fgrep) są przestarzałe (nawet jeśli nadal mogą działać).
Timo,
27

Jeśli chcesz korzystać z wielu gałęzi ( |as or), to aby być bardziej kompatybilnym, lepiej wyraźnie powiedzieć, że chcesz użyć „nowoczesnego RE”, znanego również jako. ERE.

Aby to zrobić, użyj grep -E :

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

Aby dowiedzieć się więcej o RE, ERE i całej „nowoczesnej” historii ER zobacz man 7 regex.

Alternatywnie możesz użyć egrepzamiast grep, ale jak możesz przeczytać z man grep:

egrep jest taki sam jak grep -E. fgrep jest taki sam jak grep -F

(...)

Bezpośrednie wywołanie jako egrep lub fgrep jest przestarzałe

Michał Šrajer
źródło
Chociaż bezpośrednie wywoływanie egrep jest przestarzałe, będzie działać w większości wariantów * nix.
Mark D