Çok satırlı bir metin dosyasındaki süslü ayraçlar arasındaki tüm metni nasıl silebilirim?


10

Misal:

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

Aşağıdaki gibi olmalıdır:

This is 
that wants
 anyway.

Forumda bazı benzer konuları buldum , ancak çok satırlı kıvırcık parantezlerle çalışmıyor gibi görünüyorlar.

Mümkünse, grep, sed, awk ... vb. Tabanlı çözümler gibi tek satırlık bir yöntemi tercih ederim.

DÜZENLEME: Çözümler iyi gibi görünüyor, ancak orijinal dosyalarımın köşeli parantez yuvalama içerdiğini fark ettim. Bu yüzden yeni bir soru açıyorum. Herkese teşekkürler: Çok satırlı bir metin dosyasındaki iç içe geçmiş köşeli ayraçlar arasındaki tüm metni nasıl silebilirim?


1
Bunu deneyinsed '/{/{:1;N;s/{.*}//;T1}' multiline.file
Costas

Yanıtlar:


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

Açıklama:

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

    Bu, tüm dosyayı desen alanına okur.

    :againbir etikettir. Nsonraki satırda okur. son satır olmaması şartıyla etikete $!b againgeri döner again.

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

    Bu, parantez içindeki tüm ifadeleri kaldırır.

Mac OSX'te şunları deneyin:

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

İç İçe Braces

Bunu birçok iç içe parantez içeren bir test dosyası olarak ele alalım:

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

İç içe parantezleri işlemek için bir değişiklik:

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

Açıklama:

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

    Bu öncekiyle aynıdır: dosyanın tamamını okur.

  • :b

    Bu bir etiket tanımlar b.

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

    Bu, iç parantez içermediği sürece metni parantez içindeki kaldırır.

  • t b

    Yukarıdaki yedek komut bir değişikliğe neden olduysa, etikete geri dönün b. Bu şekilde, tüm küme grupları kaldırılıncaya kadar yedek komut tekrarlanır.


Cevabınız mükemmel görünüyor. Açtığım yeni soru (orijinal soruyu okuyun EDIT) tam olarak aynı olmadığı sürece, sanırım siz de cevaplamalısınız. Forum kurallarına uygun olur mu?
Sopalajo de Arrierez

@ John1024, OP aynı konuda yeni bir soru gönderdiği için düzenlemenizi buraya taşıyabilirsiniz .
Ramesh

1
TAMAM. Oraya kopyaladım ve yeni sorudaki örnek metni kullanmak için değiştirdim.
John1024

5

Perl:

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

Yerinde düzenleme yapmak istiyorsanız

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

Bu dosyayı tek bir dize olarak okur ve genel bir arama ve değiştirme yapar.

Bu, iç içe parantezleri işleyecektir:

perl -ne 'do {$b++ if $_ eq "{"; print if $b==0; $b-- if $_ eq "}"} for split //'

Teşekkür ederim, bu çok yardımcı oldu! Bu bana bir..hiç ile sed ile mücadele vs içinde bir fonksiyonun içeriğini değiştirmek için bir yapı komut dosyası ile bir sorunu çözmek için yardımcı oldu ah, em, daha fazla zaman o zaman (saat .. öksürük .. öksürük)
AndrewD

4

sed:

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

doğrultusunda beri başlayan {ve (sonraki hat almak Nyerine (kadar) {}yapılabilir) ( Tvasıta tarafından yapılan işaretlemek dönmek :ikamesi yapılan değilse)

Bir satırda çok sayıda curle varsa, biraz doğru olarak değiştirin

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

Parantez içindeki tüm sembolleri kaldırın ( açgözlü olmamak için hariç her sembol[^}] eşittir ) ve hatta kalırsa - eğer yoksa, bir sonraki satır eklenir .right bracketsedleft brackedright bracket

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.