cari dan ganti sed dengan pola multiline

2

Saya memiliki file yang isinya sebagai berikut:

alfa
[many lines here]
TAG1
TAG2

bravo
TAG3

charlie
TAG4
[many lines here]

di mana TAG1, TAG2, TAG3 dan TAG4 adalah string tetap dan alfa, bravo dan charlie mengubah waktu ke waktu, dan saya ingin mengekstrak:

alfa-bravo-charlie

Apa perintah sed tepatnya yang harus saya gunakan? Saya tidak tahu cara bekerja dengan pola multi-line. :(

PS: Saya menggunakan sed untuk windows.

Toc
sumber

Jawaban:

3

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.

dubiousjim
sumber
1

Dari contoh Anda tidak jelas apa yang Anda coba lakukan. Sepertinya Anda mencoba untuk membuang seluruh isi file selain dari satu set tiga penanda, yang ingin Anda gabungkan bersama. Anda tidak perlu sed untuk ini, Anda cukup mengetik:

echo alfa-bravo-charlie

Dan Anda telah mencapai tujuan Anda. Jika Anda hanya ingin menghapus konten antara "alfa" dan "charlie", Anda dapat menggunakan skrip sed seperti ini:

/charlie/ a\
alfa-bravo-charlie
/alfa/,/charlie/ d

Jika ini bukan yang ingin Anda lakukan, mungkin membantu jika Anda ingin menjelaskan contoh Anda.

larsks
sumber