Tiga sed
perintah berbeda :
sed '$!N;s/"[^"]*"\n<[^>]*>/other characters /;P;D'
sed -e :n -e '$!N;s/"[^"]*"\n<[^>]*>/other characters /;tn'
sed -e :n -e '$!N;/"$/{$!bn' -e '};s/"[^"]*"\n<[^>]*>/other characters /g'
Mereka bertiga membangun di atas s///
perintah ubstitusi dasar :
s/"[^"]*"\n<[^>]*>/other characters /
Mereka juga semua berusaha untuk berhati-hati dalam menangani baris terakhir, karena sed
cenderung berbeda pada output mereka dalam kasus tepi. Inilah artinya $!
alamat yang cocok dengan setiap baris yang !
bukan yang $
terakhir.
Mereka juga semua menggunakan N
perintah ext untuk menambahkan baris input berikutnya ke pola ruang mengikuti \n
karakter ewline. Siapa pun yang telah lama sed
belajar akan belajar untuk bergantung pada \n
karakter ewline - karena satu-satunya cara untuk mendapatkannya adalah dengan meletakkannya secara eksplisit di sana.
Ketiganya berusaha untuk membaca input sesedikit mungkin sebelum mengambil tindakan - sed
bertindak secepat mungkin dan tidak perlu membaca seluruh file input sebelum melakukannya.
Meskipun mereka melakukan semuanya N
, ketiganya berbeda dalam metode rekursi mereka.
Perintah Pertama
Perintah pertama menggunakan N;P;D
loop yang sangat sederhana . Tiga perintah ini terintegrasi untuk POSIX-compatible sed
dan saling melengkapi satu sama lain dengan baik.
N
- seperti yang telah disebutkan, menambahkan N
baris input ext ke pola-ruang setelah \n
pembatas ewline yang dimasukkan .
P
- seperti p
; itu P
memecah pola-ruang - tetapi hanya sampai dengan \n
karakter ewline pertama yang terjadi . Maka, diberi input / perintah berikut:
printf %s\\n one two | sed '$!N;P;d'
sed
P
hanya satu . Namun, dengan ...
D
- seperti d
; itu D
menghapus pola-ruang dan memulai siklus baris lain. Tidak seperti d
, D
menghapus hanya sampai garis tepi pertama yang terjadi \n
di pola-ruang. Jika ada lebih banyak ruang-pola mengikuti \n
karakter ewline, sed
mulailah siklus baris berikutnya dengan yang tersisa. Jika d
dalam contoh sebelumnya diganti dengan D
, misalnya, sed
akan P
memecah satu dan dua .
Perintah ini hanya muncul untuk baris yang tidak cocok dengan s///
pernyataan ubstitusi. Karena s///
ubstitusi menghapus \n
ewline yang ditambahkan N
, tidak pernah ada yang tersisa ketika sed
D
menghapus pola-ruang.
Tes dapat dilakukan untuk menerapkan P
dan / atau D
secara selektif, tetapi ada perintah lain yang lebih sesuai dengan strategi itu. Karena rekursi ini dilaksanakan untuk menangani garis berturut-turut yang cocok hanya bagian dari aturan pengganti, urutan berturut-turut dari garis pencocokan kedua ujung dari s///
ubstitution tidak bekerja dengan baik .:
Diberikan masukan ini:
first "line"
<second>"line"
<second>"line"
<second>line and so on
... itu mencetak ...
first other characters "line"
<second>other characters line and so on
Namun, itu menangani
first "line"
second "line"
<second>line
...baik baik saja.
Perintah Kedua
Perintah ini sangat mirip dengan yang ketiga. Keduanya menggunakan label :b
peternakan / t
est (seperti juga ditunjukkan dalam jawaban Joeseph R. di sini ) dan kembali lagi ke sana dengan syarat tertentu.
-e :n -e
- sed
skrip portabel akan membatasi :
definisi label dengan \n
ewline atau -e
pernyataan xecution inline baru .
:n
- mendefinisikan label bernama n
. Ini dapat dikembalikan kapan saja dengan bn
atau tn
.
tn
- t
perintah est kembali ke label yang ditentukan (atau, jika tidak ada yang disediakan, keluar dari skrip untuk siklus baris saat ini) jika ada s///
pengganti karena label itu ditentukan atau karena yang terakhir disebut t
ests berhasil.
Dalam perintah ini rekursi terjadi untuk garis yang cocok. Jika sed
berhasil mengganti pola dengan karakter lain , sed
kembali ke :n
label dan coba lagi. Jika tidak terjadi s///
ubstitusi, cetak sed
pola-ruang dan mulailah siklus-baris berikutnya.
Ini cenderung menangani urutan berturut-turut dengan lebih baik. Di mana yang terakhir gagal, ini mencetak:
first other characters other characters other characters line and so on
Perintah Ketiga
Seperti disebutkan, logika di sini sangat mirip dengan yang terakhir, tetapi tes lebih eksplisit.
/"$/bn
- ini adalah sed
ujian. Karena b
perintah ranch adalah fungsi dari alamat ini, sed
hanya akan b
ranch kembali ke :n
setelah \n
ewline ditambahkan dan pola-ruang masih berakhir dengan "
tanda kutip ganda.
Ada sedikit yang dilakukan antara N
dan b
mungkin - dengan cara ini sed
dapat dengan cepat mengumpulkan input sebanyak yang diperlukan untuk memastikan bahwa baris berikut tidak sesuai dengan aturan Anda. The s///
ubstitution berbeda di sini bahwa itu mempekerjakan g
bendera lobal - dan sehingga akan melakukan semua penggantian diperlukan sekaligus. Diberikan input identik perintah ini menghasilkan identik dengan yang terakhir.
\n
pernyataan ewline Anda membuat sebabnya saya bertanya. orang jarang bertanya apakah mereka bisa melakukans//\n/
apa yang Anda bisa dengan GNUsed
, meskipun kebanyakan orang lainsed
akan menolak pelarian itu di sisi kanan. tetap saja, jalan\n
keluar akan bekerja di sebelah kiri dalam POSIX apa punsed
dan Anda dapat menerjemahkannya dengan mudah seolah-y/c/\n/
olah itu akan memiliki efek yang sama sepertis/c/\n/g
dan karenanya tidak selalu berguna.