Problema de regex Grep 'OR'

65

Estou tentando usar grep com um regex para encontrar linhas em um arquivo que corresponde a 1 de 2 possíveis seqüências de caracteres. Aqui está o meu grep:

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

O grep acima não retorna resultados. No entanto, se eu executar:

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

ou

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

Eu combino linhas específicas. Por que minha regex OR não corresponde? Obrigado antecipadamente pela ajuda!

dr.bunsen
fonte

Respostas:

94

Com regex normal, os personagens (, |e )necessidade de ser escapado. Então você deve usar

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

Você não precisa de escapes ao usar a opção estendida regex ( -E). Veja a man grepseção " Basic vs Extended Regular Expressions".

rozcietrzewiacz
fonte
10
Você também pode usar em egrepvez de grep -E.
Riccardo Murri
2
@RiccardoMurri A resposta de Michal afirma que o egrep (e o fgrep) está obsoleto (mesmo que ainda funcione).
Timo
27

Se você quiser usar vários ramos (o |quanto or), em seguida, para ser mais compatível, é melhor explícita dizer que você quer usar "RE moderna" aka. ANTES.

Para fazer isso, use grep -E :

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

Para saber mais sobre ER, ERE e toda a história "moderna" de ER, consulte man 7 regex.

Como alternativa, você pode usar em egrepvez de grep, mas como pode ler em man grep:

egrep é o mesmo que grep -E. fgrep é o mesmo que grep -F

(...)

A chamada direta como egrep ou fgrep está obsoleta

Michał Šrajer
fonte
Enquanto a chamada direta do egrep estiver obsoleta, ela funcionará na maioria das variantes * nix.
Mark D