Sepertinya
cat sed_data.txt | sed 's/\b[0-9]\{3\}\b/NUMBER/g'
saya harus keluar dari karakter untuk membentuk ekspresi reguler. Dalam hal ini saya harus melarikan diri kawat gigi untuk ditafsirkan sebagai beberapa kali.
Mengapa? Saya berharap semuanya akan menjadi karakter regex kecuali lolos. Yaitu sebaliknya.
11
s/regex//g
sudah mengharapkan regex dan saya berharap itu adalah teks yang perlu untuk melarikan diriJawaban:
Ini karena
sed
menggunakan POSIX BREs (Basic Regular Expressions) yang bertentangan dengan EREs (Extended Regular Expressions) yang mungkin Anda gunakan dari Perl atau teman.Dari
sed(1)
halaman manual:Kutipan yang relevan dari tautan di atas:
Dikutip kata demi kata dari komentar Craig Sanders :
sumber
-r
atau--regexp-extended
baris perintah. Ini berguna jika Anda ingin menghindari membongkar skrip sed Anda dengan melarikan diri secara berlebihan.sed
implementasi lain (ketika mereka mendukung ERE, sebagian besar BSD) cenderung menggunakan-E
untuk itu sebagai gantinya (yang lebih masuk akal karena itu adalah pilihan yang sama seperti untukgrep
. Mengapa GNUsed
memilih-r
adalah misteri bagi saya).Itu karena alasan historis.
Regexp pertama kali diperkenalkan di Unix di
ed
utilitas pada awal 70-an. Meskipuned
didasarkan padaqed
yang pelaksanaannya oleh penulis yang sama dipahami regexp lebih kompleks,ed
hanya dipahami^
,$
,[...]
,.
,*
dan\
untuk melarikan diri semua hal di atas.Sekarang, ketika kebutuhan untuk memiliki lebih banyak operator muncul, cara harus ditemukan untuk memperkenalkan mereka tanpa merusak kompatibilitas. Jika skrip digunakan untuk menggunakan
s
ed
perintahs/foo() {/foo (var) {/g
untuk mengganti semua instancefoo() {
denganfoo(var) {
dan Anda memperkenalkan(
atau{
operator, itu akan merusak skrip itu.Namun tidak ada skrip yang akan dilakukan
s/foo\(\) {/foo\(var\) {/
, karena itu sama dengans/foo() {/foo(var) {/
dan tidak ada alasan untuk melarikan diri(
karena itu bukan operator RE. Jadi memperkenalkan operator baru\(
atau\{
tidak merusak kompatibilitas karena sangat tidak mungkin untuk memecahkan skrip yang ada menggunakan sintaks yang lebih lama.Jadi, itulah yang dilakukan. Kemudian,
\(...\)
ditambahkan pada awalnya hanya untuks
ed
perintah untuk melakukan hal-hal sepertis/foo\(.\)/\1bar/
dan kemudian sebagaigrep '\(.\)\1'
(tetapi bukan hal-hal seperti\(xx\)*
).Dalam UnixV7 (1979, hampir satu dekade kemudian), bentuk baru ekspresi reguler ditambahkan dalam utilitas baru
egrep
danawk
disebut extended regular expression (karena mereka adalah alat baru, tidak ada kompatibilitas mundur yang harus dilanggar). Akhirnya, ia menyediakan fungsionalitas yang tersedia di Ken Thompson kunoqed
(operator pergantian|
, pengelompokan(..)*
) dan menambahkan beberapa operator seperti+
dan?
(tetapi tidak memiliki fitur backref dari ekspresi reguler dasar).Kemudian BSD ditambahkan
\<
dan\>
(ke BRE dan ERE), dan SysV ditambahkan\{
dan\}
ke BRE saja.Tidak sampai lebih lama dari
{
dan}
ditambahkan ke ERE, dengan melanggar kompatibilitas ke belakang. Tidak semua orang menambahkannya. Misalnya, GNUawk
hingga versi 4.0.0 (2011) tidak mendukung{
kecuali dipaksa ke mode kesesuaian POSIX.ketika GNU
grep
ditulis pada awal 90-an, ia menambahkan semua barang dari BSD dan SysV (seperti\<
,{
) dan alih-alih memiliki dua sintaks dan mesin regexp terpisah untuk BRE dan ERE, mengimplementasikan operator yang sama di keduanya, hanya rekan-rekan BRE dari(
,?
,{
,+
harus didahului dengan backslash (agar kompatibel dengan implementasi lainnya BRE). Itu sebabnya Anda dapat melakukannya.\+
di GNUgrep
(meskipun itu bukan POSIX atau didukung oleh implementasi lain) dan Anda dapat melakukannya(.)\1
di GNUegrep
(meskipun itu bukan POSIX atau didukung oleh banyak implementasi lain termasuk GNUawk
).Menambahkan
\x
operator bukan satu-satunya cara untuk menambahkan lebih banyak operator dengan cara yang kompatibel mundur. Misalnyaperl
digunakan(?...)
. Itu masih kompatibel dengan EREs karena(?=...)
tidak berlaku di EREs, sama untuk.*?
.vim
untuk operator serupa melakukannya secara berbeda dengan memperkenalkan\@=
atau.\{-}
misalnya.sumber