Bir dize arayın ve bir aralık içinde önce ve sonra her şeyi yazdırın


9

Bu dosya var:

sometext1{
string1
}

sometext2{
string2
string3
}

sometext3{
string4
string5
string6
}

Belirli bir dize için bu dosyayı aramak ve açılıştan önce bu dizeden önce {ve kapanışa kadar bu dizeden sonra her şeyi yazdırmak istiyorum }. Sed ile bunu başarmaya çalıştım ama /{/,/string2/örneğin sed'deki her şeyi yazdırmaya çalışırsam sed yazdırır:

sometext1{
string1
}

sometext2{
string2
sometext3{
string4
string5
string6
}

Dize "string2" için arama yaparsanız çıktı olması gerekir:

sometext2{
string2
string3
}

Teşekkürler.


Şimdi, daha sonra silmek için orijinal dosyadaki çıkış satır numaralarına ihtiyacım olduğunu buldum. Mikeserv'in şanssız verdiği komutu değiştirmeyi denedim, sed'in tutma fonksiyonu ile biraz kafam karıştı.
rodrigo

peki, geez, rodrigo, kendinden başka kimseye söylemedin. yapılabilir, ama en iyi şekilde yapılır grep -n '' <infile | sed .... sedKomutlar modifiye edici gerekecektir; özellikle satır başı bağlantılarını arayan /adres /bitleri ^. Benim cevap kullanıyormuş Yani, muhtemelen yapabileceği: grep -n '' | sed 'H;/{$/h;/^[^:]*:}/x;/{\n.*PATTERN/!d'. Tüm çıktı satırlarının önüne orijinal dosyanın satır numaraları ve ardından iki nokta üst üste 1:sometext1{\n2:string1vb. Gelir . sedher çıkış satırının bir sayı ile açılması dışında yalnızca daha önce filtreleyeceği şeye filtre uygular.
mikeserv

Yanıtlar:


9

İşte iki komut. .*{$Bir dizideki son satıra kadar kesen bir komut istiyorsanız (@don_crissti'nin yaptığı gibi ed) şunları yapabilirsiniz:

sed 'H;/{$/h;/^}/x;/{\n.*PATTERN/!d'

... ewline karakterini Hizleyerek her satırı eski alana ekleyerek , eşleşen her satır için eski alanın \nüzerine yazarak ve heşleşen her satır {$için heski ve desen alanlarını değiştirerek ^}ve böylece arabelleğini temizleyerek çalışır.

Yalnızca ewline ile {sonra bir \nnoktada eşleşen satırları yazdırır PATTERNve bu yalnızca arabellek değişiminin hemen ardından gerçekleşir.

Bir dizi maçtaki {$diziyi sondaki sonuncuya kadar seçer, ancak aşağıdakileri içeren her şeyi alabilirsiniz:

sed '/PATTERN.*\n/p;//g;/{$/,/^}/H;//x;D'

Yaptığı şey , hher ...{$.*^}.*sekans için takas deseni ve eski boşlukları , ewline karakterini Htakip eden sekans içindeki tüm satırları eski boşluğa ekler \nve Dkalanlarla \nyeniden başlamadan önce her satır döngüsü için desen uzayında ilk oluşan ewline karakterine kadar çıkar.

Elbette, \ndesen alanında ewline aldığı tek zaman , bir giriş satırının ^}- aralığınızın sonu - eşleşmesi ve böylece komut dosyasını başka bir durumda yeniden çalıştırması, her zamanki gibi bir sonraki giriş satırını çekmesidir.

Yine PATTERNde \newline ile aynı desen alanında bulunduğunda, ^}tekrar üzerine yazmadan önce lotu yazdırır (böylece aralığı sonlandırabilir ve arabelleği temizleyebilir) .

Bu girdi dosyası göz önüne alındığında (teşekkürler don) :

sometext1{
string1
}

sometext2{
PATTERN
string3
}

sometext3{
string4
string5
string6
}

Header{
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}
}

İlk baskılar:

sometext2{
PATTERN
string3
}
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}

...ve ikinci...

sometext2{
PATTERN
string3
}
Header{
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}

@don_crissti - Bilmem. Bu sadece bir satır başında diziyi sınırlandırır }. Bunun için faydalı olabilir ... open{\nsub;\n{ command; }\n}; close- ama burada olanlardan emin değilim ...
mikeserv

Merhaba @mikeserv - Burada ortaya çıkan benzer bir soru var unix.stackexchange.com/questions/232509/… , çözümünüz küçük dosya üzerinde çalışıyor, ancak büyük bir dosyam var ve " Alanın taşmasına izin ver " alıyorum. hata mesajı. Herhangi bir şansın var mı, bunu nasıl çözebilirim? Çok teşekkürler
Narayan Akhade

@NarayanAkhade - hayır. neyse, revizyon olmadan. sürece ... {...}bloklarla birlikte olmayan büyük girdi genişlikleri var mı? Durum buysa ve ilk çözümü kullanıyorsanız /{$/,/^}/H, başlangıçta sadece yerine yapabilirsiniz H. Ancak ikinci çözümü de denediyseniz ve yine de aynı hatayla karşılaşırsanız, bu muhtemelen yardımcı olmaz çünkü yardımcı olmaz. Ayrıca indirim de yapmayın ed. don burada çok iyi bir cevap var ve mem arabellek taşmasını önlemek gerekir edgeçici tampon dosyaları da çok basit kullanmak için uygulanabilir .
mikeserv

6

İşte bir çözüm ed:

ed -s filename <<< $'g/PATTERN/?{?,/}/p\nq\n'

yani:

g/PATTERN/     # mark each line matching PATTERN  
?{?,/}/p       # for each marked line, print all lines from the previous { up to the next }  
q              # quit editor

Bu PATTERN, her bir çift arasında yalnızca bir satır olduğunu varsayar , { }aksi takdirde PATTERNaynı blok içinde bulunan her ek satır için yinelenen çıktı alırsınız . Tek bir satır eşleşmesi içeren
birden çok iş için çalışır; örneğin , iki farklı bölümde bulunan bir test dosyası için :{ }PATTERNPATTERN

sometext1{
string1
}

sometext2{
PATTERN
string3
}

sometext3{
string4
string5
string6
}

Header{
sometext4{
some string

string unknown

here's PATTERN again

another string here
}
}

çalışan

ed -s sample <<< $'g/PATTERN/?{?,/}/p\nq\n'

çıktılar:

sometext2{
PATTERN
string3
}
sometext4{
some string

string unknown

here's PATTERN again

another string here
}

Aslında bundan çok şey aldım! Çok teşekkürler!
mikeserv

Bu komutun var olduğunu bile bilmiyorum. Teşekkürler
rodrigo

4

İle pcregrep:

pcregrep -M '(?s)\{[^}]*PATTERN.*?\}'

Veya grepgirdi NUL bayt içermiyorsa GNU ile :

grep -Poz '.*(?s)\{[^}]*PATTERN.*?\}'

0
$ awk 'BEGIN{RS="\n\n"; FS="[{}]"} {if ($2 ~ /string4/) {print $2}}' t1.txt
string4
string5
string6

nerede:

  • string4 -> eşleştirilecek dize
  • t1.txt -> sorguda belirtilen dosya içeriğini içerir

-2

sed -n '/ string / p' dosya adı

sed bastırılmış sed'in varsayılan davranışına eklendiğinde -n bu deyim size tam olarak ne istediğinizi vermeyebilir ama sadece dizeyi değiştirmelidir

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.