Ini bekerja dengan gnu sed, saya tidak berpikir itu bergantung pada ekstensi khusus gnu tapi saya tidak tahu.
echo "$yourdata" | sed -ne '1{h;d}; /^TAG1$/ {n; /^TAG2$/{n;N;N; /\nTAG3$/ {s///; H; n;N;N; /\nTAG4$/ {s///; H; g; s/\n\n/-/gp; q; } } } }'
Hasil: alfa-bravo-charlie
Bagaimana cara kerjanya? Pertama kita beri tahu "-n" kita tidak ingin mencetak apa pun kecuali kita secara spesifik mengatakan [p] rint.
Blok pertama dari ekspresi sed adalah "1 {h; d}". Ini mengatakan ketika kita membaca baris 1, simpanan baris itu di buffer lama [h] lalu [d] hapus dari buffer yang berfungsi sehingga kita akan membaca baris berikutnya dan meneruskannya melalui ekspresi sed dari awal.
Saat membaca baris berikutnya, blok "1 {...}" akan dilewati.
Kami tidak mencocokkan apa pun lebih jauh sampai kami mencapai garis TAG1. Pada titik ini kita menjalankan blok {...} yang panjang. Ini mengatakan pertama baca baris [n] ext, menimpa baris TAG1 yang ada di buffer. Jika buffer sekarang adalah TAG2, maka kita menjalankan blok {...} berikutnya. Yang pertama membaca baris [n] ext, menimpa apa yang sudah ada di buffer. Dua perintah berikutnya adalah "N; N". Ini berarti membaca 2 baris berikutnya tetapi tambahkanmereka ke buffer kerja, daripada menimpanya. Jika buffer kerja sekarang cocok dengan / \ nTAG3 $ /, maka kami menjalankan blok {...} berikutnya. Yang mengatakan pertama "s ///", dengan kata lain gantikan string kosong untuk ekspresi yang paling cocok baru-baru ini. Ini menghapus "\ nTAG3" dari akhir buffer yang berfungsi, meninggalkan "\ nbravo". Kemudian kita lakukan [H], yang menambahkannya ke buffer terus. ([h] menimpa penahan penahan, [H] menambahkannya). Jadi sekarang buffer penahan berisi baris pertama "alfa", lalu baris berikutnya "\ nbravo". Ini diikuti oleh baris baru, jadi kami benar-benar mendapat "alfa \ n \ nbravo." Kami akan mengurus dua baris baru nanti.
Kami terus berjalan sampai kami mendapat "alfa \ n \ nbravo \ n \ ncharly" di buffer penahan. Lalu kita katakan [g] et buffer terus (menimpa apa pun yang ada di buffer bekerja). Kami melakukan "s / \ n \ n / - /" pada ini untuk mengubah garis ganda ganda menjadi garis putus-putus. Kami menambahkan bendera "g" dan "p" di akhir perintah [s] sehingga pergantian bekerja secara global (yaitu tidak hanya melakukan satu pergantian kemudian berhenti) dan bahwa hasil setelah pergantian [p] dilubangi.
Kemudian kita [q] uit, kita tidak perlu membaca sisa aliran input.