Çok satırlı bir metin dosyasında iç içe geçmiş süslü ayraçlar arasındaki tüm metni nasıl silebilirim?


9

Bu soru , çok satırlı bir metin dosyasındaki süslü ayraçlar arasındaki tüm metni nasıl silebilirim? (aynı, ancak yuvalama gereksinimleri olmadan).

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.

Bunu bir çeşit tek satır bash komutu (awk, sed, perl, grep, cut, tr ... vb) ile yapmak mümkün mü?

Yanıtlar:


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

Açıklama:

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

    Bu dosyanın tamamını okur.

    :againbir etikettir. Nsonraki satırda $!Nokur ve zaten son satırda olmamak koşuluyla bir sonraki satırda okur. son satır olmaması şartıyla etikete $!b againgeri döner again.

  • :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.


3

Bir Perl yaklaşımı:

$ perl -F"" -a00ne 'for (@F){$i++ if /{/; $i||print; $i-- if /}/}' file
This is 
that wants
 anyway

açıklama

  • -a: Tarafından verilen dosya sınırlayıcı otomatik ayrılma konulu dönüşler -Fiçine @Fdiziden.
  • -F"": giriş alanı ayırıcısını boş olarak ayarlar ve her öğenin @Fgiriş karakterlerinden biri olmasına neden olur .
  • -00: "paragraf modu" nu açın, burada "satır" iki ardışık satır karakteri olarak tanımlanır. Bu, bu durumda tüm dosyanın tek bir satır olarak ele alınacağı anlamına gelir. Dosyanızda çok sayıda paragraf varsa ve köşeli ayraçlar birden çok paragraf içerebilirse, -0777bunun yerine kullanın.
  • -ne: bir girdi dosyasını okuyun ve -eher satıra verilen komut dosyasını uygulayın .

Betiğin kendisi aslında oldukça basittir. Sayaç, a {her görüldüğünde bir artar ve her biri için bir azaltılır }. Bu, sayaç 0 olduğunda parantezlerin içinde olmadığımız ve yazdırmamız gerektiği anlamına gelir:

  • for (@F){}: @Fsatırdaki her karakterin her bir öğesi için bunu yapın .
  • $i++ if /{/;: $ibu karakter bir{
  • $i||print;: $iayarlanmadığı sürece yazdır (0 ayarlanmamış olarak sayılır).
  • $i-- if /}/: $ibu karakter bir}
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.