sed
API adalah primitif - dan ini adalah desain. Setidaknya, itu tetap primitif dengan desain - apakah itu dirancang secara primitif pada awal saya tidak bisa mengatakan. Dalam kebanyakan kasus, penulisan sed
skrip yang, ketika dijalankan, akan menghasilkan skrip lainsed
memang masalah sederhana. sed
sangat sering diterapkan dengan cara ini oleh preprocessor makro seperti m4
dan / atau make
.
(Berikut ini adalah kasus penggunaan yang sangat hipotetis: ini adalah masalah yang direkayasa agar sesuai dengan solusi. Jika terasa seperti peregangan bagi Anda, maka itu mungkin karena itu, tetapi itu tidak selalu membuatnya kurang valid.)
Pertimbangkan file input berikut:
cat <<"" >./infile
camel
cat dog camel
dog cat
switch
upper
lower
Jika kami ingin menulis sed
skrip yang akan menambahkan kata -case ke ekor setiap kata yang sesuai dalam file input di atas hanya jika dapat ditemukan pada baris dalam konteks yang sesuai , dan kami ingin melakukannya seefisien mungkin ( sebagaimana seharusnya menjadi tujuan kita, misalnya, selama operasi kompilasi) maka kita harus memilih untuk menghindari penerapan /
regexp /
sebanyak mungkin.
Satu hal yang mungkin kita lakukan adalah mengedit file di sistem kita sekarang, dan tidak pernah menelepon sed
sama sekali selama kompilasi. Tetapi jika salah satu dari kata-kata dalam file tersebut harus atau tidak boleh dimasukkan berdasarkan pengaturan lokal dan / atau opsi waktu kompilasi, maka melakukan hal itu kemungkinan tidak akan menjadi alternatif yang diinginkan.
Hal lain yang mungkin kita lakukan adalah memproses file sekarang melawan regexps. Kami dapat memproduksi - dan memasukkan dalam kompilasi kami - sebuah sed
skrip yang dapat menerapkan pengeditan sesuai dengan nomor baris - yang biasanya merupakan rute yang jauh lebih efisien dalam jangka panjang.
Sebagai contoh:
n=$(printf '\\\n\t')
grep -En 'camel|upper|lower' <infile |
sed " 1i${n%?}#!/usr/heirloom/bin/posix2001/sed -nf
s/[^:]*/:&$n&!n;&!b&$n&/;s/://2;\$a${n%?}q"'
s/ *cat/!/g;s/ *dog/!/g
s| *\([cul][^ ]*\).*|s/.*/\1-case/p|'
... yang menulis output dalam bentuk sed
skrip dan yang terlihat seperti ...
#!/usr/heirloom/bin/posix2001/sed -nf
:1
1!n;1!b1
1s/.*/camel-case/p
:2
2!n;2!b2
2!!s/.*/camel-case/p
:5
5!n;5!b5
5s/.*/upper-case/p
:6
6!n;6!b6
6s/.*/lower-case/p
q
Ketika output itu disimpan ke file teks yang dapat dieksekusi pada mesin saya bernama ./bang.sed
dan jalankan seperti ./bang.sed ./infile
, output adalah:
camel-case
upper-case
lower-case
Sekarang Anda mungkin bertanya kepada saya ... Mengapa saya ingin melakukan itu? Mengapa saya tidak hanya grep
mencocokkan korek api? Lagi pula, siapa yang menggunakan case unta? Dan untuk setiap pertanyaan yang hanya bisa saya jawab, saya tidak tahu ... karena saya tidak tahu. Sebelum membaca pertanyaan ini, saya tidak pernah secara pribadi memperhatikan multi-! persyaratan parsing dalam spec - saya pikir ini adalah tangkapan yang cukup rapi.
The multi! hal itu segera masuk akal bagi saya, meskipun - banyak sed
spesifikasi diarahkan hanya diuraikan dan hanya dihasilkan sed
skrip. Anda mungkin akan menemukan \n
pembatas ewline yang diperlukan untuk [wr:bt{]
lebih masuk akal dalam konteks itu, dan jika Anda mengingat gagasan itu, Anda mungkin lebih memahami beberapa aspek spesifikasi lainnya - (seperti :
tidak menerima alamat, dan q
menolak untuk terima lebih dari 1) .
Dalam contoh di atas saya menulis formulir tertentu sed
naskah yang hanya pernah dibaca sekali. Jika Anda melihatnya dengan saksama, Anda mungkin memperhatikan bahwa ketika sed
membaca file edit, ia berkembang dari satu blok perintah ke blok perintah berikutnya - ia tidak akan pernah bercabang dari atau menyelesaikan skrip-editnya sampai benar-benar selesai dengan file editnya.
Saya menganggap itu multi-! alamat mungkin lebih berguna dalam konteks itu daripada di beberapa orang lain, tetapi, dalam kejujuran, saya tidak bisa memikirkan satu kasus di mana saya mungkin telah menggunakannya dengan sangat baik - dan saya sed
banyak. Saya juga berpikir bahwa GNU / BSD sed
gagal untuk menanganinya seperti yang ditentukan - ini mungkin bukan aspek dari spesifikasi yang banyak diminati, jadi jika suatu implementasi mengabaikannya, saya ragu dengan sangat serius bug @ box mereka akan menderita hasilnya sangat buruk.
Yang mengatakan, kegagalan untuk menangani ini sebagaimana ditentukan adalah bug untuk setiap implementasi yang berpura-pura kepatuhan, dan jadi saya pikir menembak email ke kotak dev yang relevan disebut-untuk di sini, dan saya bermaksud melakukannya jika Anda tidak melakukannya.
!
bertindak sebagai toggle,/pattern/!!
sama dengan/pattern/
, dan/pattern/!!!
sama dengan/pattern/!
. Pada beberapa FreeBSD!
sama dengan satu.