penggunaan pergantian "|" di reg sed

79

Saya menggunakan sed, GNU sed versi 4.2.1. Saya ingin menggunakan pergantian "|" simbol dalam subekspresi. Sebagai contoh :

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

harus kembali

" blib bou "

tetapi kembali

"blia blib bou blf".

Bagaimana saya bisa mendapatkan hasil yang diharapkan?

Cedric
sumber

Jawaban:

110

"|" juga membutuhkan garis miring terbalik untuk mendapatkan makna khusus.

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

akan melakukan apa yang Anda inginkan.

Seperti yang Anda ketahui, jika semuanya gagal, baca manual :-).

Manual pengguna sed GNU , bagian 3.3 Ikhtisar Sintaks Ekspresi Reguler :

`REGEXP1 \ | REGEXP2 '

Cocok dengan REGEXP1 atau REGEXP2.

Perhatikan garis miring terbalik ...

Sayangnya, sintaks regex tidak benar-benar standar ... ada banyak varian, yang berbeda antara lain di mana "karakter khusus" perlu \ dan yang tidak. Dalam beberapa itu bahkan dapat dikonfigurasi atau tergantung pada sakelar (seperti pada GNU grep, yang dapat Anda alihkan di antara tiga dialek regex yang berbeda).

Jawaban ini khususnya untuk sed GNU . Ada sedvarian lain , misalnya yang digunakan dalam BSD, yang berperilaku berbeda.

sleske
sumber
35
Untuk siapa pun yang bingung dengan jawaban ini \ | hanya bekerja di gnu sed (gsed di os x) bukan vanilla sed (sed on os x).
Andrew Hancox
@AndrewHancox Terima kasih banyak! Saya akan merobek semua rambut dari kepala saya (dan sejauh ini saya melakukan cukup baik dibandingkan dengan manajer saya di bagian depan rambut) - Saya tahu saya tahu RegEx cukup untuk mencoba | dan \ | tapi saya tidak pernah memikirkan fakta bahwa OSX mungkin menggunakan sed non-gnu.
phatskat
8
Versi BSD / OS X standar sedtidak mendukung pergantian, tetapi hanya dengan sintaks regex "extended" ( -E) - yang berarti tidak ada garis miring terbalik pada pipa atau tanda kurung:echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
Mark Reed
2
Saya mengedit jawaban saya untuk mencatat bahwa itu hanya untuk GNU sed.
sleske
23

Karena ada beberapa komentar mengenai sedimplementasi non-Gnu : Setidaknya pada OS X, Anda dapat menggunakan -Eargumen untuk  sed:

Menginterpretasikan ekspresi reguler sebagai ekspresi reguler diperluas (modern) daripada ekspresi reguler dasar (BRE's). Halaman manual re_format (7) sepenuhnya menjelaskan kedua format.

Kemudian Anda dapat menggunakan metakarakter ekspresi reguler tanpa menghindarinya. Contoh:

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

GNU sed juga mendukung -ropsi (ekspresi reguler yang diperluas). Ini berarti Anda tidak perlu melarikan diri dari karakter meta:

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

Keluaran:

hi hi
jco
sumber
Ya, -ropsi benar-benar sangat membantu untuk keterbacaan ekspresi. Itu harus menjadi jawaban yang diterima.
рüффп
9

Itu \|tidak bekerja dengan sed pada Solaris 10 baik. Apa yang saya lakukan adalah menggunakan

perl -p -e 's/bl(ia|f)//g'
Joe Tennies
sumber
2
1 untuk portabilitas karena, jika suatu sistem memiliki perl, ia akan selalu menggunakan sintaks ini, tidak seperti sed.
evilsoup
4

Tindak lanjut: sed -E memungkinkannya di MacOS. Tidak perlu backslash untuk |.

 sed -E 's/this|orthat/oooo/g' infile
beberapa ide
sumber
1

Dalam GnuWin32 pada Windows, sintaksnya adalah sed "s/thing1\|thing2/ /g" source > destination.

Kutipan harus bertipe "- ini "Diperlukan" untuk perintah yang akan diuraikan.

twobob
sumber