Dalam pengeditan
ini Stéphane Chazelas POSIXifies (lagi)sed
format saya dengan memasukkan -e
istirahat xpression dan -e
pernyataan xpression lain . Sekarang, saya mungkin hanya bertanya kepadanya mengapa dalam komentar, saya kira, tetapi sudah revisi nomor 18 pada jawaban itu dan hampir semua yang sebelumnya sudah berkat freebies serupa (jika Anda dapat melihat komentar yang dihapus Anda akan tahu apa Maksud saya) . Juga, saya pikir saya cukup dekat untuk memahami mengapa mengucapkan ini dengan cara yang mungkin lebih bermanfaat secara umum. Jadi, inilah harapan ...
Saya biasanya lebih suka menjaga total sed
-e
xpressions saya menjadi satu jika saya bisa, tetapi saya juga memiliki preferensi yang lebih besar untuk menyesuaikan dengan spesifikasi sedekat mungkin, terutama ketika perbedaannya tidak lebih dari a <space>
dan a -e
. Tetapi saya tidak dapat melakukan ini jika saya tidak mengerti mengapa saya harus melakukannya. Berikut ini ikhtisar singkat dari pemahaman saya saat ini:
yang
' -e '
istirahat portable dapat berdiri di untuksed
naskah\n
istirahat ewline dalamsed
pernyataan command-line ... Aku memang kabur tentang mengapakurung kurawal dalam suatu
sed
{
fungsi}
harus didahului dengan\n
jeda baris seperti yang dinyatakan di sini:- Ini
<right-brace>
harus didahului oleh a<newline>
dan dapat didahului atau diikuti oleh<blank>
karakter.
- Ini
sebuah
\n
istirahat ewline juga sama diperlukan berikut setiap penggunaan ...a
,b
,c
,i
,r
,t
,w
, atau:
.
Tapi saya tidak mengerti dengan jelas bagaimana definisi {
fungsi }
berhubungan dengan !
operator yang tidak. Satu-satunya penyebutan yang saya temukan dari operator negasi di negara bagian spesifikasi:
- Fungsi dapat didahului oleh satu atau lebih
!
karakter, dalam hal ini fungsi tersebut akan diterapkan jika alamat tidak memilih ruang pola.
Apakah ini berarti bahwa penggunaan kawat gigi !
menyiratkan ? Bagaimana dengan perintah - haruskah mereka juga dipisahkan oleh istirahat? Apakah ini yang dialamatkan ketika Stéphane baru-baru ini MEMPIPTAKAN jawaban saya?{
}
$!
' -e '
Saya pikir itu adalah !
operator negasi, atau itu adalah b
pernyataan peternakan yang ia alamatkan dalam editnya - atau mungkin keduanya sekaligus - tetapi saya tidak tahu dan ingin melakukannya. Jika hanya satu b
pernyataan peternakan, maka saya yakin suatu d
akan lakukan di tempat dan menghilangkan kebutuhan untuk ' -e '
istirahat, tapi aku lebih suka menjadi tertentu sebelum hazarding sebuah tiga kali POSIXified jawaban. Bisakah kamu menolong?
Saya melakukan mengambil risiko itu setelah semua , tapi tidak dengan pasti besar ...
b;n;:b
, Anda bercabang ke label yang disebut";n;:b"
sed historis dan POSIX (dan sed GNU tidak dalam hal itu).:
bagiannya - Anda menyetir pulang beberapa bulan yang lalu. Tapi saya tidak sepenuhnya mengerti mengapased
perintah kedua juga POSIXified .sed
sangat tidak jelas bagi saya. Saya telah meminta klarifikasi beberapa kali di masa lalu, tetapi saya rasa itu tidak diperbarui. Tes yang baik adalah dengan mencoba dengan heirloom toolchest (Solaris one, berasal dari aslinya dan yang menjadi dasar spesifikasi POSIX).s///
ubstitutions khusus untuk menerima rantai dengan ; . itu menjadi kabur di sekitar perintah yang harus dibatasi dengan baris baru dan bagaimana-e
bisa bertahan dalam kasus itu - setidaknya itu berlaku untuk saya. Namun saya belum tersandung padased
yang tidak menafsirkan mereka cukup dipertukarkan sekalipun.;
sebelum baris baru - baris baru baik-baik saja. Jujur, Anda bisa melakukannya tanpa-e
dan semuanya sepenuhnya dan hanya menulis file seperti#!/bin/sed
dengan setiap perintah pada baris baru - atau orang-orang yang tidak memerlukan pembatas seperti itu malah dipisahkan;
. Orang-orang yang melakukan memerlukan baris biasanya orang-orang yang mengambil input sewenang-wenang -:
nama label dan perintah yang merujuk kepada mereka sepertib
ataut
atau menutup}
curlies untuk fungsi, ataur
benar-benar menyebalkan danw
ritual yang mengambil args nama file. Mereka semua perlu diikuti\n
.Jawaban:
Jadi sudah saatnya pertanyaan ini dijawab, dan, meskipun saya akhirnya secara intuitif menemukan cara untuk melakukan ini dengan benar di hampir setiap kasus beberapa waktu lalu, saya baru-baru ini berhasil mengonkretkan pemahaman dengan teks dalam standar. . Itu sebenarnya dinyatakan di sana cukup sederhana - Aku hanya bodoh mengabaikannya berkali-kali, kurasa.
Bagian-bagian yang relevan dari teks semuanya ditemukan di bawah judul ...
Perintah Pengeditan di
sed
:Teks argumen harus terdiri dari satu atau lebih baris. Setiap
\n
garis tepi yang disematkan dalam teks harus didahului dengan\
garis miring terbalik. Garis miring terbalik lainnya dalam teks harus dihapus, dan karakter berikut harus diperlakukan secara harfiah.The
r
danw
kata kerja perintah, danw
bendera kes
perintah, mengambil opsional RFILE (atau wfile ) parameter, dipisahkan dari kata kerja perintah surat atau flag oleh satu atau lebih<blank>s
; implementasi dapat memungkinkan pemisahan nol sebagai perpanjangan.Perintah verba selain
{
,a
,b
,c
,i
,r
,t
,w
,:
, dan#
dapat diikuti oleh;
koma, opsional<blank>s
, dan kata kerja perintah lain. Namun, ketikas
kata kerja perintah digunakan denganw
bendera, mengikutinya dengan perintah lain dengan cara ini menghasilkan hasil yang tidak ditentukan....di...
Opsi: Beberapa
-e
dan-f
opsi dapat ditentukan. Semua perintah harus ditambahkan ke skrip dalam urutan yang ditentukan, terlepas dari asalnya.-e
script - Tambahkan perintah pengeditan yang ditentukan oleh argumen opsi- skrip ke akhir skrip perintah pengeditan. The Script pilihan-argumen harus memiliki sifat-sifat yang sama dengan naskah operan, dijelaskan dalam operan bagian.-f
script_file - Tambahkan perintah pengeditan di file script_file ke akhir skrip.Dan terakhir di ...
Operan:
\n
ewline.Jadi, ketika Anda mengambilnya sama sekali, masuk akal bahwa setiap perintah yang secara opsional diikuti oleh parameter arbitrer tanpa pembatas yang telah ditentukan (sebagai lawan
s d sub d repl d flag
misalnya) harus membatasi pada\n
ewline yang tidak terhindar.Dapat diperdebatkan bahwa itu
;
adalah pembatas yang telah ditentukan tetapi dalam kasus menggunakan perintah;
untuk salah satu[aic]
akan mengharuskan parser terpisah dimasukkan dalam implementasi khusus untuk tiga perintah - terpisah, yaitu, dari parser yang digunakan untuk[:brw]
, misalnya. Atau implementasi harus mengharuskan backslash;
juga lolos dalam parameter teks dan hanya tumbuh lebih rumit dari sana.Jika saya menulis sesuatu
sed
yang saya inginkan sesuai dan efisien, maka saya tidak akan menulis parser yang terpisah, saya harapkan - kecuali bahwa mungkin[aic]
harus membuat kesalahan sintaks jika tidak segera diikuti oleh\n
ewline. Tapi itu adalah masalah tokenization sederhana - kasus pembatas akhir umumnya yang lebih bermasalah. Saya hanya akan menuliskannya demikian:...dan...
... akan berperilaku sangat mirip, karena yang pertama akan membuat dan menulis ke file bernama:
... dan yang kedua akan menambahkan blok teks ke baris saat ini pada output seperti ...
... karena keduanya akan berbagi kode parsing yang sama untuk parameter.
Dan mengenai
{ ... }
dan$!
masalah - yah, saya jauh dari sana. Perintah tunggal yang didahului oleh alamat bukanlah fungsi melainkan perintah yang ditujukan. Hampir semua perintah - termasuk{
definisi fungsi}
ditentukan untuk menerima/one/
atau/one/,/two/
alamat - dengan pengecualian#
komentar dan:
definisi label . Dan sebuah alamat dapat berupa nomor baris atau express biasa dan dapat dinegasikan dengan!
. Jadi semuanya ...... dapat diikuti oleh
;
lebih banyak perintah sesuai dengan standar, tetapi jika lebih banyak perintah diperlukan untuk satu alamat, dan alamat itu tidak harus dievaluasi ulang mengikuti eksekusi setiap perintah, maka suatu{
fungsi}
harus digunakan seperti:... di mana
{
tidak dapat diikuti pada baris yang sama dengan penutupan}
dan bahwa penutupan}
tidak dapat terjadi kecuali pada awal garis. Tetapi jika perintah yang terkandung seharusnya tidak diikuti oleh\n
ewline, maka perintah tersebut tidak harus berada dalam fungsi juga. Jadi semuas///
ubstitutions di atas - dan bahkan}
kurung kurawal, dapat dengan mudah diikuti oleh;
titik koma dan perintah lebih lanjut.Saya terus berbicara tentang
\n
pembatas ewline tetapi pertanyaannya adalah tentang-e
pernyataan xpression, saya tahu. Tapi keduanya benar-benar satu dan sama, dan hubungan utamanya adalah bahwa skrip dapat berupa argumen baris perintah literal atau file dengan salah satu-[ef]
, dan keduanya ditafsirkan sebagai file teks (yang ditentukan untuk diakhiri dengan\n
ewline) tetapi keduanya tidak perlu diakhiri dengan\n
ewline. Dengan ini saya bisa reasonbly (saya berharap) mengambil kesimpulan bahwa\0NUL
argumen dibatasi menyiratkan berakhir\n
ewline, dan karena semua argumen doa mendapatkan setidaknya) sebuah\0NUL
pembatas pula, maka baik harus bekerja dengan baik.Bahkan, dalam prakteknya, dalam setiap kasus kecuali satu di mana standar menentukan
\
backslash lolos dari baris baru harus diminta, saya telah menemukan ...... bekerja dengan baik juga. Dan dalam setiap kasus - sekali lagi, dalam praktik - di mana
\n
ewline yang tidak lolos harus diminta ...... telah bekerja untuk saya juga. Satu-satunya pengecualian yang saya sebutkan di atas adalah ...
... yang tidak berfungsi untuk implementasi apa pun di salah satu pengujian saya. Saya cukup yakin bahwa jatuh kembali ke persyaratan file teks dan fakta yang
s///
datang dengan pembatas dan jadi tidak ada alasan pernyataan tunggal harus span\0NUL
argumen dibatasi.Jadi, sebagai kesimpulan, berikut adalah ikhtisar singkat cara portabel untuk menulis beberapa jenis
sed
perintah:Untuk salah satu dari
[aic]
:...atau...
Untuk setiap dari
[:rwtb]
mana parameter adalah opsional (untuk semua tapi:
) tetapi pembatasan\n
ewline adalah tidak . Perhatikan bahwa saya tidak pernah memiliki alasan untuk mencoba beberapa parameter label baris seperti yang akan digunakan[:tb]
, tetapi bahwaw
riting /r
eading ke beberapa baris dalam parameter file [rw] biasanya diterima tanpa pertanyaan olehsed
s. Saya telah menguji selama embedded\n
ewline lolos dengan\
backslash. Namun, standar tidak secara langsung menentukan bahwa label dan parameter file [rw] harus diuraikan secara identik ke teksparameter dan tidak menyebutkan\n
ewline tentang dua yang pertama kecuali karena membatasi mereka....atau...
... di mana di
<space>
atas adalah opsional untuk[:tb]
.Dan terakhir...
...atau...
... di mana salah satu perintah yang disebutkan di atas (kecuali
:
) juga menerima setidaknya satu alamat dan yang dapat berupa/
regexp/
atau nomor baris dan dapat dinegasikan dengan!
, tetapi jika lebih dari satu perintah diperlukan untuk satu evaluasi alamat maka kurung{
fungsi}
pembatas konteks fungsi harus digunakan. Suatu fungsi dapat berisi bahkan beberapa\n
perintah yang dibatasi ewline, tetapi masing-masing harus dibatasi di dalam kurung kurawal seperti yang seharusnya.Dan itulah cara menulis
sed
skrip portabel .sumber