Dosyalarda çok satırlı dizeyi değiştirme


17

Bir çok satırlı dizeyi başka bir çok satırlı dize ile değiştirerek güncellemek istediğim birkaç dosya var. Çizgileri boyunca bir şey:

* Some text, 
* something else
* another thing

Ve bununla değiştirmek istiyorum:

* This is completely
* different text

Sonuç olarak, değiştirildikten sonra ilk metin bloğunu içeren dosya şimdi ikinci dizeyi içerecektir (dosyanın geri kalanı değişmez).

Sorunun bir kısmı, dosya sisteminde güncellenecek dosyaların listesini bulmak zorunda olmasıdır. Bunun için grep kullanabilirsiniz sanırım (yine de çok satırlı dizeleri ile yapmak o kadar kolay değil) sonra sed belki boru?

Bunu yapmanın kolay bir yolu var mı? Sed bir seçenek ama garip çünkü \ n vb eklemek zorunda. "Bu dosyadan girdi almak, bu dosyalarda eşleşen, sonra bu diğer dosyanın içeriği ile değiştirmek" demenin bir yolu var mı? Gerekirse python kullanabilirim, ancak hızlı ve basit bir şey istiyorum, bu yüzden mevcut bir yardımcı program varsa, daha çok kendi komut dosyamı yazmaktan (bunu nasıl yapacağımı biliyorum) kullanmak istiyorum.


Bunun için muhtemelen perl kullanmalısınız. stackoverflow.com/questions/1030787/…
orion

3
Yani some text, something else another thingbirden fazla çizgiyi kaplayıp kaplamamasıyla eşleşmek mi istiyorsunuz ? Yoksa sadece eşleşmek some text,\nsomething else\nanotherthingmi istiyorsun ?
mikeserv

2
Sorunuzu düzenleyin ve her bir dosyanın içeriklerinin tam olarak ne olduğunu ve istenen çıktının ne olduğunu açıklayın.
jimmij

Dize birden çok satıra yayılır. Eşleme / değiştirme sırasında boşlukları görmezden geliyorum çünkü hepsi tamamen aynı olmayabilir, ancak sadece 1-1 maç (newlines ve all) yaparsam büyük bir anlaşma değil.
ventsyv

Yanıtlar:


12

Bir veya daha fazla girdi dosyasındaki "new" dosyasının içeriğine göre "Bazı ... \ n ... Şey" yazın

perl -i -p0e 's/Some.*?thing\n/`cat new`/se' input.txt ...
  1. -i input.txt dosyasını doğrudan değiştirmek için
  2. -p0 girdi dosya dosyasını slurp ve sonunda yazdır
  3. s/regexp/.../s regexp .içinde.|\n
  4. s/.../exp/e ile değiştir eval(exp)
  5. yeni - yedek metni içeren bir dosya (Bu tamamen ... farklı metin)
  6. faydalıysa orijinal metni genişletebilirsiniz s/Some text\n...\n...thing\n/...

Aynı dosyayı (çok satırlı) içeriğini aramak için "önce" adında bir dosya ile nasıl yapabilirim? Denedim ama işe yaramıyor.
Kvothe

@Kvothe, daha fazla ayrıntıya ihtiyacımız var ... "Önce" nin özel karakterleri olmadığını varsayarak deneyebilirsinizperl -i -p0e ' $b= `cat before`; s/$b/Some thing\n/se' input.txt ...
JJoao

Ve "önce" varsayıldığında, "ve" hariç tüm özel karakterleri (yeni satırlar, eğik çizgiler, köşeli ayraçlar) içerdiğini varsayarsak.
Kvothe

5
sed -e :n -e '$!N;/\n.*\n/!{$!bn
};  s/some text,\n* *something else\n* *another thing/this is completely\
different text/;P;D' <infile

Sorunun somut bir tanımını yapana kadar size uygun bir çözüm bulmakta zorlanacağınızdan korkuyorum - ama gördüğüm kadarıyla KG sizin için en uygun olanı bu. Belki bu size bir fikir verecektir - giriş dosyasında bir seferde sadece bir satır ileriye doğru giderken her zaman bir seferde 3 satır - bir satırda 2 satır - devam edecektir.

Birden fazla satıra yayılmış olsun ya da olmasın, dizenizi eşleştirebilmelidir - yani üçe kadar. Ancak bu hükmün değiştirilmesinde yansıtılması için herhangi bir hüküm yoktur - her zaman yazılı olarak iki satırı kapsar.


0

Güçlü değil (çünkü ikinci dize çekmeyin, ancak yerleşmesi kolay) ve olabilir posix derleyici değil, çok basit:

sed '/^Some text/{:1;/another thing$/!{N;b 1}
     s/.*/this is completely\ndifferent text/g}' input.txt

İlk komut Başka bir şeyle karşılaşana kadar Bazı metinden satır ekleyin, ardından ikinci satır diğer metne dönüştürün.

Not - Sınırlama, bazı metinlerin her zaman başka bir şey izlemesi gerektiğidir .


Sorun, dizenin 2 satırdan (bir düzine kadar) fazla olabileceği ve sekmeler, * vb. Gibi kaçması gerekebilecek başka şeyler içerebileceğidir.
ventsyv

@ventsyv Satır veya ayırıcı sayısıyla ilgili bir sorun yok; komut dosyası yalnızca başlangıcı ve bitişi kontrol ediyor. Başlangıç ​​dizesi istisnai olarak metni değiştirmek için işaretleyebilir EĞER oldukça yeterli . Daha iyi değilseniz, doğru desen üretmek için giriş örneğini gösterin.
Costas
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.