Eşleşen çizgiden eşleşen çizgiyi ve n. Çizgiyi yazdır


18

Eşleşen satır ve eşleşen satırdan (aradığım ifade içeren satır) 4 satır yazdırmaya çalışıyorum.

Aşağıdaki kodu kullanıyorum: sed -n 's/^[ \t]*//; /img class=\"devil_icon/,4p' input.txt

Ancak bu yalnızca eşleşen çizgiyi yazdırır.

Bu yalnızca 4. satırı yazdırır. awk 'c&&!--c;/img class=\"devil_icon/{c=4}' input.txt

Hem eşleşen satırı hem de 4. satırı yazdırmam gerekiyor.


Kullanım egrep "pattern" -A4
Valentin Bajrami

@ val0x00ff aralarındaki satırları da basar .. yani: eşleşen satırdan başlayarak sonraki 4 satırı yazdırır
debal

"Eşleşen çizgiyi ve 4. çizgiyi eşleşen çizgiden yazdırmaya çalışıyorum" diyorsunuz. Bu grep -A 4 "pattern" file | sed -n '4p'sana yanlış anlama ediyorum sürece, tam olarak ne istediğinizi yapar
Valentin Bajrami

hayır değil. Yukarıdaki kodun çıktısı </td>4. satır değildi
debal

Yanıtlar:


18

Awk, bunu aşağıdaki gibi yapardın

awk '/pattern/{nr[NR]; nr[NR+4]}; NR in nr' file > new_file`

veya

awk '/pattern/{print; nr[NR+4]; next}; NR in nr' file > new_file`

açıklama

İlk çözüm eşleşen tüm satırları bulur pattern. Bir eşleşme bulduğunda, kayıt numarasını ( NR) dizide saklar nr. NRAynı diziden gelen 4. kaydı da saklar . Bu tarafından yapılır nr[NR+4]. NRDaha sonra her kayıt ( ) nrdizide mevcut olup olmadığını kontrol eder , eğer öyleyse kayıt yazdırılır.

İkinci çözüm esas olarak aynı şekilde çalışır, ancak patternbu satırla karşılaştığında, o satırı yazdırır ve daha sonra 4. kaydı dizide saklar nr, sonra bir sonraki kayda gider. Sonra awkbu 4. kayıtla karşılaştığında NR in nrblok yürütülür ve sonra bu +4 kaydı yazdırır.

Misal

İşte bir örnek veri dosyası sample.txt,.

$ cat sample.txt 
1
2
3
4 blah
5
6
7
8
9
10 blah
11
12
13
14
15
16

1. çözümü kullanma:

$ awk '/blah/{nr[NR]; nr[NR+4]}; NR in nr' sample.txt 
4 blah
8
10 blah
14

2. çözümü kullanma:

$ awk '/blah/{print; nr[NR+4]; next}; NR in nr' sample.txt 
4 blah
8
10 blah
14

3
Güzel, +1. awkBurada çok fazla kısayol kullanıyorsunuz , kısa bir açıklama ekleyebilir misiniz (örneğin awk'de ima edilen ve dizilerin ilişkilendirilebilir olduğu gibi şeyler)?
terdon

@terdon ile bir anlaşma lütfen kodu biraz açıklayabilir misiniz?
debal

@slm Tam cevabı geliştirdiğiniz ve sağladığınız için teşekkür ederiz!
Valentin Bajrami

1
Cevabınız için teşekkürler, ben de onunla yeni bir şey öğrendim.
slm

4
sed -n 's/^[ \t]*/; /img class=\"devil_icon/,+4 { 3,5d ; p }' input.txt

Yazdırmadan önce, uygun satırların silinmesini ekliyorum { 3,5d ; p }.


ifadeniz bir hata üretir: sed: -e expression #1, char 18: unknown option to s'`
mineraller

4

Eşleşen çizgiden sonra kaç satır yazdırılacağını belirten -Aseçeneği deneyebilirsiniz grep. Bunu ile birleştirin sedve gerekli satırları alacaksınız.

grep -A 4 pattern input.txt | sed -e '2,4d'

Tuşunu kullanarak sedikinci satırdan dördüncü sıraya kadar sileriz.


3
Bu pattern, dosyada tek bir eşleşme olduğunu varsayar .
terdon

2

İşte Perl'de rastgele sayıda eşleşen satırla başa çıkabilen bir yol:

perl -ne '/pattern/ && do{$c=$.; print}; $.==$c+4 && print' file > new_file`

Perl. özel değişken $.geçerli satır numarasıdır. Yani, her eşleşen satır bulduğumda pattern, onu yazdırıyorum ve satır numarasını olarak kaydediyorum $c. Ardından, geçerli satır numarası önceden yazdırılandan 4 daha fazla olduğunda tekrar yazdırırım.


0
awk 'c&&!--c;/img class=\"devil_icon/{c=4};/img class=\"devil_icon/' input.txt

Aslında bul ve değiştir yapıyorsun. Aynı komuta sadece bir buluntu ekleyebilirsiniz ve her ikisini de yazdıracaktır :)

awk 'c&&!--c;/pattern/{c=4};/pattern/' input.txt
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.