Birden çok satırı dosyadaki tek bir kelimeyle nasıl değiştirebilirim (yerinde değiştirme)?


9

Dosyamın içeriği filenameaşağıdaki gibidir (örneğin):

My block of line starts from here 
START
First line
second line
third line
END
and end to here for example.

Ben arasındaki satır bloğunu değiştirmek istiyor STARTve ENDbirlikte örneğin sadece tek kelime ile SINGLEWORD. Aşağıdaki gibi:

My block of line starts from here 
SINGLEWORD
and end to here for example.

Bu komutu kullanarak satır bloğumu bulabilirim:

grep -Pzo "START(.|\n)*END" filename

Ve yukarıdaki komutun çalıştırılmasının sonucu şöyle olacaktır:

START
First line
second line
third line
END

Sonra tüm satırları tek bir satırda birleştirmek için bu komutu kullandım:

LAST_RESULT | sed -e :a -e '/$/N; s/\n/ /; ta'

O zaman bu sonucu alacağım:

START First line second line third line END

Ve son komutumla LAST_RESULTS | sed 's/.*/SINGLEWORD/'onları değiştiriyorum "SINGLEWORD"ve bu sonucu elde ediyorum.

SINGLEWORD

Şimdi ne istiyorum: Bu komutu (veya öneri komutunuzu) nasıl kullanabilir ve satır bloğumu "SINGLEWORD" kelimesiyle nasıl değiştirebilirim? Ve nihai sonuç bu dosya gibi olacak:

My block of line starts from here 
SINGLEWORD
and end to here for example.

Yanıtlar:


14

Bu çok kolay bir şekilde yapılabilir perl:

$ perl -i -p0e 's/START.*?END/SINGLEWORD/s' file
$ cat file
My block of line starts from here 
SINGLEWORD
and end to here for example. 

açıklama

-0 satır ayırıcıyı null değerine ayarlar

-ptarafından verilen komut dosyasını -eher satıra uygulayın ve bu satırı yazdırın

Normal ifade değiştirici:

  • /sDizeyi tek satır olarak ele al. Yani, .normalde eşleşmeyeceği herhangi bir karakterle, hatta yeni satırla eşleşecek şekilde değiştirin.

Neden ?:

  • Varsayılan olarak, sayısallaştırılmış bir alt desen "açgözlü" dür, yani desenin geri kalanının eşleşmesine izin verirken mümkün olduğunca çok kez (belirli bir başlangıç ​​konumu verildiğinde) eşleşir. Mümkün olan en az sayıda eşleşmesini istiyorsanız, niceleyiciyi a ile izleyin ?.

@KasiyA: Kullanmak sedmümkün ama muhtemelen daha zor olmalı (Bu soruya bakın )
Sylvain Pineau

Bir daha benim BAŞLANGIÇ ve BİTİŞ desen özel karakter (çünkü /, *, ?onun içinde) ve bunlar sadece örnektir. ve emrinizi açıklayabilir misiniz?
αғsнιη

@KasiyA sen \ ile böyle karakterler kaçabilir (tam olarak olduğu gibi sed): \/, \*,\?
Sylvain Pineau

@KasiyA denedim perl -i -p0e 's/\/\*.*?\*\//SINGLEWORD/sm'. Çalışmalı
Sylvain Pineau

@KasiyA Sanırım şimdi açıklamalarla işim bitti;)
Sylvain Pineau

14

Bu olmadan mümkün olup olmadığını merak edildi perl, pythonve diğerleri. Ve bu çözümü kullanarak buldum sed:

$ sed ':a;N;$!ba;s/START.*END/SINGLEWORD/g' filename

Açıklama:

  1. : a 'a' etiketi oluştur
  2. N desen uzayına sonraki satırı ekler
  3. , $! son satır değilse , ba dalı (git) 'a' etiketi
  4. s yerine , /START.*END/göre SINGLEWORD, g / (olabildiğince çok kez) Genel maç

Bu bulundu burada .

@KasiyA, teşekkür ederim birçok ilginç şey öğrendim!

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.