grepping bằng cách sử dụng “|” nhà điều hành thay thế


96

Sau đây là ví dụ về một tệp lớn có tên 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

Tôi đang gặp sự cố khi trích xuất các dòng cụ thể từ tệp này bằng grep. Tôi muốn trích xuất tất cả các dòng thuộc loại "gen" hoặc loại "exon", được chỉ định trong cột thứ ba. Tôi đã rất ngạc nhiên khi điều này không hoạt động:

grep 'gene|exon' AT5G60410.gff

Không có kết quả nào được trả lại. Tôi đã sai ở đâu?


8
Hãy thử egrepthay thế.
Keith

egrep có gần với loại regex mà Perl sử dụng không? (đây là một trong những Tôi đã sử dụng trước đó)
MattLBeck

Câu trả lời:


136

Bạn cần phải thoát khỏi |. Sau đây sẽ làm công việc.

grep "gene\|exon" AT5G60410.gff

argh, tôi vừa nhận ra rằng tôi đã làm theo hướng dẫn regex sai để sử dụng trong grep. Tôi dường như không thể tìm thấy một chiếc grep tốt ở bất cứ đâu. Cám ơn vì cái này!
MattLBeck

51

Theo mặc định, grep xử lý các ký tự đặc biệt điển hình như các ký tự bình thường trừ khi chúng được thoát. Vì vậy, bạn có thể sử dụng như sau:

grep 'gene\|exon' AT5G60410.gff

Tuy nhiên, bạn có thể thay đổi chế độ của nó bằng cách sử dụng các biểu mẫu sau để thực hiện những gì bạn đang mong đợi:

egrep 'gene|exon' AT5G60410.gff
grep -E 'gene|exon' AT5G60410.gff

28

Đây là một cách khác nhau để đưa ra một số lựa chọn:

grep -e gene -e exon AT5G60410.gff

công -etắc chỉ định các mẫu khác nhau để phù hợp.


bây giờ câu hỏi là cái gì nhanh hơn? có ai biết không
Stalinko

1
@stalinko: bạn có thể sử dụng timelệnh để tìm hiểu.
Nathan Fellman

2

Điều này sẽ hoạt động:

grep "gene\|exon" AT5G60410.gff

2
giá trị không câu trả lời này có mà điều này stackoverflow.com/a/6775943/3933332 không có?
Rizier123

3
@ Rizier123 - nhìn vào dấu thời gian, cả hai đều trả lời vào những thời điểm gần giống nhau với cùng một câu trả lời.
xmnboy

Đúng, chỉ chậm một phút. Tuy nhiên, tôi sẽ xóa một câu trả lời giống với câu trả lời được ủng hộ. Đặc biệt là nếu tôi đã có 40k danh tiếng.
Attila Csipak

0

Tôi đã tìm thấy câu hỏi này trong khi truy cập vào một vấn đề cụ thể mà tôi đang gặp phải liên quan đến một lệnh liên kết với một greplệnh sử dụng toán tử thay thế trong một regex, vì vậy tôi nghĩ rằng tôi sẽ đóng góp câu trả lời chuyên biệt hơn của mình.

Lỗi mà tôi gặp phải hóa ra là với toán tử đường ống trước đó (tức là |) chứ không phải toán tử thay thế (tức là |giống hệt với toán tử đường ống) trong grep regex. Câu trả lời cho tôi là thoát đúng cách và trích dẫn các ký tự shell đặc biệt cần thiết chẳng hạn như & trước khi giả định vấn đề là với grep regex của tôi liên quan đến toán tử luân phiên.

Ví dụ: lệnh tôi đã thực thi trên máy cục bộ của mình là:

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

Lệnh này dẫn đến lỗi sau:

-bash: syntax error near unexpected token `|'

Lỗi này đã được sửa chữa bằng cách thay đổi lệnh của tôi thành:

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

Bằng cách thoát &ký tự bằng dấu ngoặc kép, tôi đã có thể giải quyết vấn đề của mình. Câu trả lời không liên quan gì đến hoạt động luân phiên cả.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.