Çıktıyı yalnızca desen bulduktan sonra yazdır


13

echoerBir grup bilgiyi taramak için yazdırılan bir komut dosyası (diyelim ). Çizgileri yalnızca bir desen bulunduktan sonra görebilmek istiyorum.

Bir şeye benzemek için bir çözüm kullanıldığını hayal ediyorum

echoer | solution_command <pattern>

İdeal patternolarak düzenli bir ifade olurdu, ama benim için zor değer dizeleri yeterli olurdu.


Öyleyse desen birden çok dize olabilir mi?
Inian

Bir küre mi? Normal bir ifade mi demek istiyorsun? Globs yalnızca dosya adı genişletmeleri için anlamlıdır.
terdon

@Inian Soruyu anladığımdan emin değilim. Bunun disfonksiyonlarla çalışmasını isteyip istemediğimi mi sormak istiyorsun?
user23146

Yanıtlar:


21

AWK bunu herhangi bir normal ifadenin kullanılmasına izin veren desen aralıklarıyla yapabilir:

echoer | awk '/pattern/,0'

echoerilk satır eşleşmesinden başlayarak çıktısını basacaktır pattern.

AWK örüntü tabanlıdır ve tipik olarak “bu örüntü eşleşiyorsa, bunu yapın” tipinde bir yaklaşımla kullanılır. “Bu patern”, “bu patern eşleştiğinde, bu diğer patern eşleşene kadar bunu yapmaya başlayın” olarak tanımlanan bir patern aralığı olabilir; bu, yukarıdaki gibi virgülle ayrılmış iki desen yazarak belirtilir. Desenler /pattern/, mevcut satırın desene göre kontrol edildiği, normal ifade olarak yorumlandığı gibi, metin eşleşmeleri olabilir ; ayrıca genel ifadeler olabilir, her satır için değerlendirilebilir ve sonuçları sıfırdan farklı veya boş değilse eşleşecek şekilde değerlendirilebilir.

AWK'da, varsayılan eylem geçerli satırı yazdırmaktır.

Tüm bunları bir araya getirmek, awk '/pattern/,0'eşleşen satırları arar patternve bir tane bulduğunda, koşul eşleşene kadar 0(sıfır olmayan) tüm satırlara varsayılan eylemi uygular . awk '/pattern/,""'çok işe yarar.

Gawk manuel çok daha ayrıntılı anlatır.


3
Aralık sonu olarak sıfır ile aralık semantiğinin farkında değildim. Teşekkürler!
Kusalananda

@StephenKitt Bu harika! Eşleşene kadar yazdırmak istersem ne olur 0? Olur /pattern/,/0/mu? Yanıt, varsayılan eylemi açıkça yazmak gibi bir şey olabilir mi?
user23146

@ user23146 evet, /pattern/,/0/“0” içeren bir satır (kayıt) bulana kadar yazdırır. Parçacığı açık bir eylemle yanıtta yazmak /pattern/,0 { print $0 }eşit olarak verir /pattern/,0 { print }.
Stephen Kitt

7

sed@ StephenKitt'in awkbirinin zorunlu karşılığı :

sed '/pattern/,$!d'

patternBir şekilde orada yorumlanır Temel Düzenli İfade gibi grep(aksine Genişletilmiş Düzenli İfade içinde awk/ egrep/ grep -E). Bazı seduygulamalarda bunun yerine Genişletilmiş Düzenli İfadeler yapmak için -E(BSD, ast, son GNU / busybox, yakında POSIX) veya -r(GNU, ssed, busybox, bazı yeni BSD) seçenekleri vardır ve bazılarında bunu yapmak için (ast) veya (ssed) vardır perl benzeri düzenli bir ifade.-P-R

İle perl:

perl -ne 'print if /pattern/ .. undef'

4

GNU ve * BSD grep ile:

grep -A1000000000 pattern file

Dosyanız 1 milyondan fazla satır içermiyorsa, hepsi bu kadar.


0

Komuttan lessçıktı görüntülemek için bir çağrı cihazı kullanıyorsanız

less +pattern

0

awk ilk kalıp eşleşmesinden sonraki (ancak içermeyen) satırlar için

Tetikleyici kalıbı içeren çizgi "BURAYA KESLE" ile eşdeğerse, basılı çıktıdan çıkartabilirsiniz:

echoer | awk 'flag ; /pattern/ { flag=1 }'

Her girdi satırı awk kodundaki iki bileşenden geçer. Birinci bileşen, flagawk "değişken flagsıfır değilse, satırı yazdır" olarak yorumlanır . Awk değişkenleri varsayılan olarak 0 olduğundan, bu başlangıçta hiçbir şey yazdırmaz.

İkinci bileşen, /pattern/ { flag=1 }örüntüyü algılar algılamaz bayrağı 1 olarak ayarlar ve bayrak bu değeri çalışmanın geri kalanında tutar.

Desenin ilk algılanmasıyla birlikte, bu girdi satırını yazdırma fırsatı geçti. Sonraki tüm satırlar (deseni içeren ek satırlar dahil) yazdırılır.


0

darbe

Biraz hantal, ama işe yarıyor.

#!/bin/bash
found=false
while IFS= read -r; do
    if $found || [[ $REPLY =~ pattern ]]; then
        found=true
        printf '%s\n' "$REPLY"
    fi
done

Bu sürüm güveniyor cat, ancak anlaşılması daha kolay.

#!/bin/bash
while IFS= read -r; do
    if [[ $REPLY =~ pattern ]]; then
        printf '%s\n' "$REPLY"
        break
    fi
done
cat
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.