Bir metin bulduktan sonra belirli satırları nasıl okuyabilirim?


12

Bazı metinleri bulduktan sonra belirli sayıda satırı nasıl okuyabilirim?

Örneğin.:

"Unix" i bulduktan sonra sonraki 2 satırı okuyun:

Test 1
Test 2
Test 3
Test 4
UNIX
Test 5
Test 6
Test 7
Test 8
Test 9

Sonuç şunlar olabilir:

Test 5
Test 6

Not: Son örnekteki "Unix" bir bağımsız değişkendir ve bu nedenle başka bir metin olabilir.

Neyim var:

Hala fikirlerim kalmadı, sadece bir ışığa ihtiyacım var. Bunu yapmak için başka bir senaryo oluşturmayı düşünmek.

Yanıtlar:


10

Bir awkçözüm:

$ awk '$0 == "UNIX" {i=1;next};i && i++ <= 2' file
Test 5
Test 6

açıklama

  • /^UNIX$/{i=1;next}: görürsek UNIX, değişkeni bir i = 1sonraki girdiye ayarlarız .

  • Değişken iayarlanırsa (gördüğümüz anlamına gelir UNIX), i && i++ <= 2yalnızca sonraki iki satırdaki doğru değere göre değerlendirilerek varsayılan eyleme UNIXneden olur .awkprint $0

  • Görmeden önce UNIX, itanımlanmamış olması ve sonrasında 3 çizgisinde başlar UNIX, iifadesi yapmak 2'den daha büyük bir değere vardı i && i++ <= 2neden false olarak değerlendirilen awkdo hiçbir şey.


Testten sonra çözüm bu hata mesajını alıyorum im: hat 1 yakınındaki hata systax hat 1 yakınındaki kurtarıyor
Soğuk

@Cold: Ne koştun? $Cevabımın başındaki işaretin komut istemi değil, kabuk istemi olduğunu lütfen unutmayın awk.
cuonglm

Başka bir değişken:awk '/^UNIX$/ {s=NR;next} s && NR<=s+2'
musiphil

@Cuonglm
Cold

@Cold: İşletim sisteminiz nedir?
cuonglm

12

Bir grepçözüm:

grep -A2 -P '^UNIX$' file

Açıklama: -A anlamı: maçtan sonraki iki satırı yazdır

Veya awk:

awk '$0=="UNIX"{getline; print; getline; print}' file

Açıklama: Bu ifade UNIX satırında ( $0=="UNIX") aranır . Bu verilirse, sonrakini tamponuna ( getline) alır ve arabelleği ( ) yazdırır print. Bu iki kez yapılır.

Veya şunu kullanın sed:

sed -n '/^UNIX$/{n;p;n;p}' file

Açıklama: UNIX ( /^UNIX$/) için arama yapar. Bu bulunursa, içindeki parçayı txecutes eder {...}. nsonraki, pbaskı anlamına gelir. Bu da iki kez yapılır.


Teşekkürler @chaos, verdiğiniz son 2 seçeneği trys edeceğim. Lütfen her seçeneğin bazı açıklamalarını ekleyin, anladım ve yapacağım.
Soğuk

Satır sayısı değişirse, son iki seçenekte kaç değişiklik yapacağım? Teşekkürler
Soğuk

@Cold düzenlememi gör. Çizgiler tekrar eğer numarasını değiştirmek için getline; print;görev awkaçıklamada veya n;p;yer sedbildirimi.
kaos

Teşekkürler @chaos, ancak satır sayısı arttıkça ifade artışı ve bence değişiklik mümkün değil. Değil mi, sence de değil mi? 100 satır varsa?
Soğuk

@Cold Daha sonra grep çözümünü kullanırdım grep -A100 -P '^UNIX$' file | tail -n +2. Kuyruk kısmı ilk haciz kaldırmaktır. Diğerlerinde (sed, awk) döngüler yazmanız gerekir, bu onu daha az basitleştirir.
kaos

4
grep -A 2 UNIX file.txt

Grep'in kılavuzunda bu seçenek açıklanmaktadır:

  -A NUM, --after-context=NUM
      Print NUM  lines  of  trailing  context  after  matching  lines.
      Places  a  line  containing  --  between  contiguous  groups  of
      matches.

Merhaba @ Twinkles, iyi cevap, ama benim grep sadece bu seçenekleri "hblcnsviw" vardır. Fakat mantık iyidir. teşekkürler
Soğuk

Bu UNIXçıktıda da yazdırılacaktır .
cuonglm

Atlamak için UNIX, boru bunu için tail: [...] | tail -n +1ya hiç sed: [...] | sed '1d'.
DopeGhoti

1
@DopeGhoti: tailve sed '1d'önerileriniz yalnızca UNIXgiriş metninde yalnızca bir kez görünüyorsa düzgün çalışır . Diğer tüm cevaplar birden fazla tekrarlamaya izin verir. Önermek daha iyi olabilir ... | grep -v UNIX. Kuşkusuz, UNIX15 ve 17. satırlarda görünürse bu dağınık hale gelir .
G-Man

Güzel nokta. Ben çok emin bu sadece içinde yapılabilir ediyorum sedçeşit ile sed '/UNIX/d;n;n;p/' /path/to/filesadece sussed ve cevap olarak gönderilen,.
DopeGhoti

0

Bu hile güzel görünüyor:

sed -n '/UNIX/{n;p;n;p}' /path/to/file

Kavramın ispatı:

$ for i in {1..9}; do echo $i; done | sed -n '/4/{n;p;n;p}'
5
6

1
Döngünüzün etrafındaki alt kabuk forgerekli değildir.
sonraki duyuruya kadar duraklatıldı.

Gerçekten de öyle değil; o kabuğun ortasında günün ortasında olduğum başka bir faffery kalıntısıydı. Parenler kaldırıldı.
DopeGhoti

0

Şunları kullanabilirsiniz ex:

ex -s +'1,/UNIX/d|%p|q!' file_or_/dev/stdin

nerede:

  • 1,/UNIX/d- maçtan sonra metni kaldırır
  • %p - tampon yazdırır
  • q!- dosyadaki değişiklikleri kaydetmeden çık ( wqyerinde düzenlemek için kullanın )
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.