GNU/Linux >> Belajar Linux >  >> Linux

SED ganti di beberapa baris

Solusi 1:

Sed bekerja berdasarkan baris demi baris. Itu dapat dibuat untuk bekerja pada banyak baris, tetapi tidak dirancang seperti itu - dan menurut saya itu pasti terlihat ketika Anda mencoba menggunakan seperti itu. Tetapi jika Anda memutuskan untuk pergi ke sana, Anda mungkin harus menggunakan register. Periksa beberapa solusi untuk https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n untuk melihat bagaimana hal itu dapat dilakukan.

Saya lebih suka menggunakan perl daripada sed untuk tugas semacam ini (berorientasi multi-baris, maksud saya). Boilerplate yang harus Anda tambahkan sebelum pencarian-dan-ganti (BEGIN... ) tidak jelas, tetapi regex menurut saya lebih bersih:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--string-->/string/smg' file.xml

Atau, menggunakan pengelompokan untuk mempersingkat ekspresi dan memungkinkan Anda menggunakan regex di sana:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--(string_or_regex)-->/\1/smg' file.xml

Itu harus bekerja baik pada kejadian dengan dan tanpa baris baru antara penanda komentar dan kode yang akan dihapus komentarnya.

Diadaptasi dari:

https://stackoverflow.com/questions/1030787/multiline-search-replace-with-perl

Solusi 2:

sed membaca setiap baris secara bergantian, sehingga tidak akan pernah cocok dengan pola multiline kecuali Anda mendorongnya ke arah yang benar. N perintah membaca satu baris dari input dan menambahkannya ke ruang pola.

sed -i -e '/^<!--$/ {
    N; /\n<Connector port="8009" protocol="AJP\/1\.3" redirectPort="8443" \/>$/ {
        N; /\n-->$/ {
            s/^<!--\n//; s/\n-->$//
        }
    }
}' /myfile.xml

Bisa dibilang, jika Anda memerlukan perintah selain s , maka Anda harus beralih dari sed dan ke awk atau perl. Berikut cuplikan Perl yang sedikit lebih fleksibel yang mengatasi komentar multibaris dengan cara yang lebih umum.

perl -i -pe '
    if (/<!--/) { $_ .= <> while !/-->/;
        s[<!--\n(<Connector port="8009" protocol="AJP/1\.3" redirectPort="8443" />)\n-->][$1];
    }' /myfile.xml

Solusi 3:

Berikut deskripsi perintah multiline di SED:http://docstore.mik.ua/orelly/unix/sedawk/ch06_01.htm

Ini adalah rasa sakit di pantat. Anda mungkin ingin mengikuti saran Eduardo dan menggunakan perl -i -p -e sebagai gantinya.

Solusi 4:

  • /<\!--/ :pencocokan string
  • :X :ini adalah label untuk perintah cabang "b"
  • /-->/ :pencocokan string
  • [email protected]@[email protected] :hapus "" dan cetak hasil
  • d :hapus ruang pola dan mulai siklus baru
  • N :jika tidak cocok dengan /-->/ lalu tambahkan baris
  • bX :cabang ke :X label
  • p :cukup cetak string yang tidak cocok dengan /