Onları içeren iki desen arasında ilk oluşum nasıl seçilir


27

Bunlar dahil olmak üzere iki model arasında ilk oluşumu nasıl seçebilirim. Tercihen sedveya awk.

Sahibim:

text
something P1 something
content1
content2
something P2 something
text
something P1 something
content3
content4
something P2 something
text

P1 ve P2 arasındaki çizgilerin ilk oluşumunu istiyorum (P1 ve P2 çizgileri dahil):

something P1 something
content1
content2
something P2 something

Yanıtlar:


22
sed '/P1/,/P2/!d;/P2/q'

... dmenzile girmeyen tüm çizgileri silerek portatif bir şekilde iş yapar !, ardından aralığın qsonuna ilk geldiğinde çalışır. P1'den önce P2 için başarısız olmaz ve GNU'ya özgü bir sözdizimi yazması gerekmez.


Mükemmel! Benimkinden çok daha iyi.
Ocak'ta

1
@muru - Otomatik yazdırmayı hedeflemeye çalışırsanız, sıkışmalardan kaçınmak genellikle daha kolaydır - bu döngü sizin için çalışsın. Yine de içine düştüğüm alışkanlık bu. Ben muhtemelen en iyi bir şekilde tarif düşünüyorum erik bir vs seçme yöntemiyle - Bir desen negating ziyade onu ararken rüzgar eğilimindedir.
mikeserv

Bu büyük fileSize işlerken asılı olacaktır.
Brain90,

@ Brain90 - yapmamalı. Şikâyetinizi güvenilir bir şekilde yeniden oluşturabiliyorsanız, sedyayınladığınız bir hata var sed.
mikeserv

1
@mikeserv Olmasaydım söylemezdim. Birkaç karakteri umursamayı umursamama konusundaki endişeniz tuhaf: Sed ifadenin /P2/qsistemimde hem sistemimde hem de olmadan çalıştığını gözlemledim ; bu kadar. Bir şey hakkında merak ediyordum ve bulduğumu paylaşmak istedim.
Alexej Magura

8

ile awk

awk '/P1/{a=1};a;/P2/{exit}' file
something P1 something
content1
content2
something P2 something

8

İçinde sed:

sed -n '/P1/,/P2/p; /P2/q'
  • -nvarsayılan yazdırmayı bastırır ve pkomutu kullanarak eşleşen adres aralıkları arasındaki satırları yazdırırsınız .
  • Normalde bu, her iki bölümle de eşleşir, bu nedenle qilk P2eşleştiğinde ( ) çıkılır.

Daha P2önce gelirse bu başarısız olur P1. Bu durumu ele almak için şunu deneyin:

sed -n '/P1/,/P2/{p; /P2/q}'

1
Katılmıyorum; mikeserv'in cevabı sizinkinden daha iyi değil.
G-Man

@ g-man - pshaw. ama ben de aynı şeyi düşünüyordum.
mikeserv

1
@gman - hayır. şimdi anladım. mayınlar daha iyi. {yığın} yok!
mikeserv

1

Kalıpları kendileri atlamak istiyorsanız, işte awkversiyon:

awk '/P2/ {exit} /P1/ {f=1; next} f' file

Benim için çalışıyor. Komutun nasıl çalıştığı hakkında biraz daha bilgi ekler misiniz?
0xAffe

1

Daha basit bir awkçözüm ( iruvar'ın cevabı ile  muru'nun cevabı arasında bir ara yarısı , ancak değişken kullanmamak):

awk '/P1/,/P2/ { print }  /P2/ { exit }'

ve, muru’nun belirttiği gibi, ilk P2 ilk P1’den önce belirirse, bu hiçbir şeyi yazmaz.

Tabii ki, tüm P1-P2 aralıklarını yazdırmak istiyorsanız:

something P1 something
content1
content2
something P2 something
something P1 something
content3
content4
something P2 something

sadece exitparçayı bırak :

awk '/P1/,/P2/ { print }'

1
awk '/P1/,/P2/{print;f=1} f&&/P2/{exit}' data

Yazdırmadan hemen sonra çıkın, önce değil.


0

Desenleri kendileri atlamak ve tek GNU sed'de yalnızca ilk eşleşen bloğu göstermek için:

sed -nre '/STARTPATTERN/ {:a;n;/ENDPATTERN/{b;};p;ba}' file
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.