Bagaimana saya bisa menghapus semua teks di antara kurung keriting dalam file teks multiline?

10

Contoh:

This is {
the multiline
text file }
that wants
{ to be
changed
} anyway.

Harus menjadi:

This is 
that wants
 anyway.

Saya telah menemukan beberapa utas yang serupa di forum, tetapi tampaknya tidak bekerja dengan tanda kurung multi-line.

Jika memungkinkan, saya lebih suka metode satu garis, seperti solusi berdasarkan grep, sed, awk ... dll.

EDIT: Solusi tampaknya baik-baik saja, tetapi saya perhatikan bahwa file asli saya termasuk kurung kurawal bersarang. Jadi saya membuka pertanyaan baru. Terima kasih semuanya: Bagaimana saya bisa menghapus semua teks di antara kurung keriting bersarang dalam file teks multiline?

Sopalajo de Arrierez
sumber
1
Coba inised '/{/{:1;N;s/{.*}//;T1}' multiline.file
Costas

Jawaban:

10
$ sed ':again;$!N;$!b again; s/{[^}]*}//g' file
This is 
that wants
 anyway.

Penjelasan:

  • :again;$!N;$!b again;

    Ini membaca seluruh file ke dalam ruang pola.

    :againadalah label. Nmembaca di baris berikutnya. $!b againcabang kembali ke againlabel dengan syarat bahwa ini bukan baris terakhir.

  • s/{[^}]*}//g

    Ini menghapus semua ekspresi dalam kurung kurawal.

Di Mac OSX, coba:

sed -e ':again' -e N -e '$!b again' -e 's/{[^}]*}//g' file

Kawat Gigi Bersarang

Mari kita ambil ini sebagai file uji dengan banyak kawat gigi bersarang:

a{b{c}d}e
1{2
}3{
}
5

Berikut ini adalah modifikasi untuk menangani kawat gigi bersarang:

$ sed ':again;$!N;$!b again; :b; s/{[^{}]*}//g; t b' file2
ae
13
5

Penjelasan:

  • :again;$!N;$!b again

    Ini sama dengan sebelumnya: ia membaca di seluruh file.

  • :b

    Ini mendefinisikan label b.

  • s/{[^{}]*}//g

    Ini menghapus teks dalam kawat gigi selama teks tidak mengandung kawat gigi dalam.

  • t b

    Jika perintah pengganti di atas menghasilkan perubahan, lompat kembali ke label b. Dengan cara ini, perintah pengganti diulangi sampai semua brace-groups dihilangkan.

John1024
sumber
Jawaban Anda tampaknya sempurna. Selama pertanyaan baru yang baru saja saya buka (baca pertanyaan asli EDIT) tidak persis sama, saya pikir Anda harus menjawabnya juga. Apakah boleh dengan aturan forum?
Sopalajo de Arrierez
@ John1024, Anda dapat memindahkan hasil edit Anda di sini karena OP memposting pertanyaan baru mengenai hal yang sama.
Ramesh
1
BAIK. Saya telah menyalinnya di sana dan memodifikasinya untuk menggunakan sampel teks dalam pertanyaan baru.
John1024
5

Perl:

perl -0777 -pe 's/{.*?}//sg' file

Jika Anda ingin mengedit di tempat

perl -0777 -i -pe 's/{.*?}//sg' file

Itu membaca file sebagai string tunggal dan melakukan pencarian global dan ganti.

Ini akan menangani penguat bersarang:

perl -ne 'do {$b++ if $_ eq "{"; print if $b==0; $b-- if $_ eq "}"} for split //'
glenn jackman
sumber
Terima kasih, ini sangat membantu! Ini membantu saya memecahkan masalah dengan skrip build untuk mengganti konten fungsi dalam beberapa menit vs berjuang dengan sed dengan ah..em, lebih banyak waktu maka saya akan mengakui (jam..bat..bat)
AndrewD
4

Sed:

sed '/{/{:1;N;s/{.*}//;T1}' multiline.file

mulai sejak baris dengan {dan dapatkan baris berikutnya ( N) sampai substitusi ( {}) dapat dibuat ( Tberarti kembali ke tanda yang dibuat oleh :jika substitusi tidak dibuat)

Sedikit memodifikasi untuk menjadi kenyataan jika banyak kurva yang di-kurung dalam satu baris

sed ':1; s/{[^}]*}// ; /{/ { /}/!N ; b1 }' multiline.file

Hapus semua simbol dalam tanda kurung ( [^}]sama dengan setiap simbol kecualiright bracket untuk membuat sedtidak serakah), dan jika di baris tetap left bracked- kembali untuk memulai dengan baris berikutnya ditambahkan jika tidak ada right bracket.

Costas
sumber