sử dụng luân phiên | | trong regex của sed


79

Tôi đang sử dụng sed, GNU sed phiên bản 4.2.1. Tôi muốn sử dụng luân phiên "|" biểu tượng trong một biểu hiện phụ. Ví dụ :

echo "blia blib bou blf" | sed 's/bl\(ia|f\)//g'

nên trở về

" blib bou "

nhưng nó trở lại

"blia blib bou blf".

Làm thế nào tôi có thể có kết quả mong đợi?

Câu trả lời:


110

"|" cũng cần một dấu gạch chéo ngược để có được ý nghĩa đặc biệt của nó.

echo "blia blib bou blf" | sed 's/bl\(ia\|f\)//g'

sẽ làm những gì bạn muốn.

Như bạn biết, nếu vẫn thất bại, hãy đọc hướng dẫn :-).

Hướng dẫn sử dụng GNU sed , phần 3.3 Tổng quan về Cú pháp biểu thức chính quy :

`REGEXP1 \ | REGEXP2 '

Phù hợp với REGEXP1 hoặc REGEXP2.

Lưu ý dấu gạch chéo ngược ...

Thật không may, cú pháp regex không thực sự được chuẩn hóa ... có nhiều biến thể, khác nhau giữa những thứ khác trong đó "ký tự đặc biệt" cần \ và không có. Trong một số, nó thậm chí có thể định cấu hình hoặc phụ thuộc vào các công tắc (như trong GNU grep, mà bạn có thể chuyển đổi giữa ba phương ngữ regex khác nhau).

Câu trả lời này đặc biệt dành cho GNU sed . Có các sedbiến thể khác, ví dụ như biến thể được sử dụng trong BSD, hoạt động khác nhau.


35
Đối với bất cứ ai khác bối rối bởi câu trả lời này \ | chỉ hoạt động trong gnu sed (gsed trên os x) chứ không phải vanilla sed (sed trên os x).
Andrew Hancox

@AndrewHancox Cảm ơn bạn rất nhiều! Tôi chuẩn bị xé hết tóc ra khỏi đầu (và cho đến nay tôi đang làm khá tốt so với người quản lý của tôi ở phía trước tóc) - Tôi biết tôi biết RegEx đủ để thử | và \ | nhưng tôi chưa bao giờ nghĩ về thực tế rằng OSX thực sự có thể sử dụng một chiếc sed không phải là gnu.
phatskat

8
Phiên bản BSD / OS X tiêu chuẩn sedkhông hỗ trợ xen kẽ, nhưng chỉ với cú pháp regex "mở rộng" ( -E) - có nghĩa là không có dấu gạch chéo ngược trên đường ống hoặc dấu ngoặc đơn:echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
Mark Reed

2
Tôi đã chỉnh sửa câu trả lời của mình để lưu ý rằng nó chỉ dành cho GNU sed.
sleske

23

Vì có một số nhận xét liên quan đến việc sedtriển khai không phải Gnu : Ít nhất là trên OS X, bạn có thể sử dụng -Eđối số để  sed:

Giải thích các biểu thức chính quy như các biểu thức chính quy mở rộng (hiện đại) thay vì các biểu thức chính quy cơ bản (BRE's). Trang hướng dẫn re_format (7) mô tả đầy đủ cả hai định dạng.

Sau đó, bạn có thể sử dụng siêu ký tự biểu thức chính quy mà không thoát khỏi chúng. Thí dụ:

$ echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
 blib bou 

12

GNU sed cũng hỗ trợ -rtùy chọn (biểu thức chính quy mở rộng). Điều này có nghĩa là bạn không phải thoát khỏi các ký tự đại diện:

echo foohello barhello | sed -re "s/(foo|bar)hello/hi/g"

Đầu ra:

hi hi

Có, -rtùy chọn thực sự hữu ích cho khả năng đọc của các biểu thức. Đó nên là câu trả lời được chấp nhận.
рüффп

9

\|cũng không hoạt động với sed trên Solaris 10. Những gì tôi đã làm là sử dụng

perl -p -e 's/bl(ia|f)//g'

2
+1 cho tính di động vì, nếu một hệ thống có perl, nó sẽ luôn sử dụng cú pháp này, không giống như sed.
evilsoup

4

Theo dõi: sed -E cho phép nó trên MacOS. Không cần dấu gạch chéo ngược cho |.

 sed -E 's/this|orthat/oooo/g' infile

1

Trong GnuWin32 trên Windows sed cú pháp là sed "s/thing1\|thing2/ /g" source > destination.

Các trích dẫn phải thuộc loại "- đây là "Bắt buộc" để lệnh được phân tích cú pháp.

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.