it-swarm.com.de

So drucken Sie 5 aufeinanderfolgende Zeilen nach einem Muster in einer Datei mit awk

Ich möchte nach einem Muster in einer Datei suchen und drucke 5 Zeilen, nachdem ich dieses Muster gefunden habe.

Ich muss awk verwenden, um dies zu tun.

Beispiel: 

Dateiinhalt:

.
.
.
.
####PATTERN#######
#Line1
#Line2
#Line3
#Line4
#Line5
.
.
.

Wie durchsuche ich eine Datei und drucke nur die oben genannten Zeilen? Benutze ich die NR der Zeile, die "PATTERN" enthält, und erhöhen Sie den Wert bis zu 5 und drucken Sie jede Zeile im Prozess Ich weiß, ob es in Awk noch ein anderes effizientes Wat gibt.

35
tomkaith13

Eine andere Möglichkeit, dies in AWK zu tun:

awk '/PATTERN/ {for(i=1; i<=5; i++) {getline; print}}' inputfile

in sed:

sed -n '/PATTERN/{n;p;n;p;n;p;n;p;n;p}' inputfile

oder

sed -n '1{x;s/.*/####/;x};/PATTERN/{:a;n;p;x;s/.//;ta;q}' inputfile

Die #-Zeichen repräsentieren einen Zähler. Verwenden Sie eine weniger als die Anzahl der Zeilen, die Sie ausgeben möchten.

49
awk '
{ 
    if (lines > 0) {
        print;
        --lines;
    }
}

/PATTERN/ {
    lines = 5
}

' < input

Dies ergibt:

#Line1
#Line2
#Line3
#Line4
#Line5
14
Johnsyweb

grep "PATTERN" search-file -A 5 erledigt die Arbeit für Sie, wenn Sie sich dazu entscheiden, grep eine Chance zu geben.

Bearbeiten: Sie können grep auch mit der Funktion system() aus Ihrem awk-Skript aufrufen.

11
anubhava

Bearbeiten: hat nicht bemerkt, dass PATTERN nicht Teil der Ausgabe sein sollte.

cat /etc/passwd | awk '{if(a-->0){print;next}} /qmaild/{a=5}'

oder

cat /etc/passwd | awk ' found && NR-6 < a{print} /qmaild/{a=NR;found=1}'

Die kürzeste, die ich mir vorstellen kann, ist:

cat /etc/passwd | awk 'a-->0;/qmaild/{a=5}'

Lesen Sie, da a zu 0 tendiert./Qmaild/setzt a bis 5 :-)

7
ninjalj

awk zur Rettung!

mit der Musterlinie drucken (insgesamt 6 Zeilen)

$ awk '/^####PATTERN/{c=6} c&&c--' file

####PATTERN#######
#Line1
#Line2
#Line3
#Line4
#Line5

muster überspringen und die nächsten fünf Zeilen drucken

$ awk 'c&&c--; /^####PATTERN/{c=5}' file

#Line1
#Line2
#Line3
#Line4
#Line5
5
karakfa

Schnelle und schmutzige Lösung: awk '/PATTERN/ {i=0} { if (i<=5) {print $0}; i+=1} BEGIN {i=6}'

0
gelraen

So begrenzt wie die Lösung von Johnsyweb, jedoch unter Verwendung eines anderen Ansatzes und der erweiterten Funktion von GNU awk, die vollständige RegEx-Datensatztrennzeichen ermöglicht, was zu einem Code führt, der IMHO sehr awk-

awk -F\\\n '{NF=5}NR-1' RS="PATTERN[^\n]*." OFS=\\\n

Wenn Sie also eine stabile Lösung suchen, die auch lesbar ist, fahren Sie mit Dennis Williamsons Antwort (+1 für diese), aber vielleicht genießen auch Sie einfach die Schönheit von awk, wenn Sie solche Zeilen betrachten.

0
mschilli