grepowanie za pomocą „|” operator alternatywny

96

Poniżej znajduje się przykład dużego pliku o nazwie AT5G60410.gff:

Chr5    TAIR10  gene    24294890    24301147    .   +   .   ID=AT5G60410;Note=protein_coding_gene;Name=AT5G60410
Chr5    TAIR10  mRNA    24294890    24301147    .   +   .   ID=AT5G60410.1;Parent=AT5G60410;Name=AT5G60410.1;Index=1
Chr5    TAIR10  protein 24295226    24300671    .   +   .   ID=AT5G60410.1-Protein;Name=AT5G60410.1;Derives_from=AT5G60410.1
Chr5    TAIR10  exon    24294890    24295035    .   +   .   Parent=AT5G60410.1
Chr5    TAIR10  five_prime_UTR  24294890    24295035    .   +   .   Parent=AT5G60410.1
Chr5    TAIR10  exon    24295134    24295249    .   +   .   Parent=AT5G60410.1
Chr5    TAIR10  five_prime_UTR  24295134    24295225    .   +   .   Parent=AT5G60410.1
Chr5    TAIR10  CDS 24295226    24295249    .   +   0   Parent=AT5G60410.1,AT5G60410.1-Protein;
Chr5    TAIR10  exon    24295518    24295598    .   +   .   Parent=AT5G60410.1

Mam problemy z wyodrębnieniem z tego określonych wierszy przy użyciu grep. Chciałem wyodrębnić wszystkie linie typu „gen” lub typu „egzon”, wymienione w trzeciej kolumnie. Zaskoczyło mnie, gdy to nie zadziałało:

grep 'gene|exon' AT5G60410.gff

Brak wyników. Gdzie popełniłem błąd?

MattLBeck
źródło
8
Spróbuj egrepzamiast tego.
Keith,
czy egrep jest bliższy rodzajowi wyrażenia regularnego, którego używa Perl? (to ten, którego używałem wcześniej)
MattLBeck

Odpowiedzi:

136

Musisz uciec z |. Poniższe powinny załatwić sprawę.

grep "gene\|exon" AT5G60410.gff
Jeff Foster
źródło
argh, właśnie zdałem sobie sprawę, że postępuję zgodnie z niewłaściwym samouczkiem dotyczącym wyrażeń regularnych do użycia w grep. Nigdzie nie mogę znaleźć dobrego grepa. Dzięki za to!
MattLBeck,
51

Domyślnie grep traktuje typowe znaki specjalne jak zwykłe znaki, chyba że są one chronione. Możesz więc użyć następującego:

grep 'gene\|exon' AT5G60410.gff

Możesz jednak zmienić jego tryb, korzystając z następujących formularzy, aby zrobić to, czego oczekujesz:

egrep 'gene|exon' AT5G60410.gff
grep -E 'gene|exon' AT5G60410.gff
a'r
źródło
28

Oto inny sposób grepowania dla kilku opcji:

grep -e gene -e exon AT5G60410.gff

przez -eprzełącznik określa różne wzory dopasować.

Nathan Fellman
źródło
teraz pytanie, co jest szybsze? czy ktoś wie?
Stalinko
1
@stalinko: powinieneś być w stanie użyć timepolecenia, aby się dowiedzieć.
Nathan Fellman
2

To zadziała:

grep "gene\|exon" AT5G60410.gff
ennuikiller
źródło
2
Jakiej wartości ma ta odpowiedź, której nie ma ten stackoverflow.com/a/6775943/3933332 ?
Rizier123
3
@ Rizier123 - spójrz na znaczniki czasu, oba odpowiedziały w prawie identycznym czasie z tą samą odpowiedzią.
xmnboy,
Tak, tylko minuta spóźnienia. Mimo to usunąłbym odpowiedź, która jest identyczna z odpowiedzią za głosem. Zwłaszcza jeśli miałbym za pasem 40 tysięcy reputacji.
Attila Csipak
0

Znalazłem to pytanie podczas wyszukiwania w Google konkretnego problemu, w przypadku którego wiązałem polecenie potokowe z greppoleceniem, które używa operatora alternacji w wyrażeniu regularnym, więc pomyślałem, że wniosę bardziej specjalistyczną odpowiedź.

Błąd, który napotkałem, okazał się być z poprzednim operatorem potoku (tj. |), A nie operatorem alternacji (tj. |Identycznym z operatorem potoku) w wyrażeniu regularnym grep. Odpowiedzią dla mnie było właściwe uciec i zacytować jako niezbędne specjalne znaki powłoki, takie jak &, zanim założyłem, że problem dotyczy mojego wyrażenia regularnego grep, które obejmowało operator alternacji.

Na przykład polecenie, które wykonałem na moim komputerze lokalnym, brzmiało:

get http://localhost/foobar-& | grep "fizz\|buzz"

To polecenie spowodowało następujący błąd:

-bash: syntax error near unexpected token `|'

Ten błąd został naprawiony, zmieniając moje polecenie na:

get "http://localhost/foobar-&" | grep "fizz\|buzz"

Unikając &znaku podwójnymi cudzysłowami udało mi się rozwiązać mój problem. Odpowiedź w ogóle nie miała nic wspólnego z operacją naprzemienną.

entpnerd
źródło