web-dev-qa-db-fra.com

Comment imprimer 5 lignes consécutives après un motif dans un fichier avec awk

Je voudrais rechercher un motif dans un fichier et imprimer 5 lignes après avoir trouvé ce motif.

Je dois utiliser awk pour le faire.

Exemple: 

Contenu du fichier:

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

Comment analyser un fichier et n’imprimer que les lignes mentionnées ci-dessus? Je sais s’il existe un autre moyen efficace de le faire à Awk.

35
tomkaith13

Une autre façon de le faire dans AWK:

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

en sed:

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

ou

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

Les caractères # représentent un compteur. Utilisez un moins que le nombre de lignes que vous souhaitez générer.

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

/PATTERN/ {
    lines = 5
}

' < input

Cela donne:

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

grep "PATTERN" search-file -A 5 fera le travail pour vous si vous décidez de donner une chance à grep.

Edit: Vous pouvez appeler grep en utilisant la fonction system() depuis votre script awk.

11
anubhava

Edit: n'a pas remarqué que PATTERN ne devrait pas faire partie de la sortie.

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

ou

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

Le plus court que je puisse trouver est:

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

Lire comme a tend à 0./qmaild/définit a à 5 :-)

7
ninjalj

awk à la rescousse!

imprimer avec la ligne de motif (total 6 lignes)

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

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

sauter le motif et imprimer les cinq lignes suivantes

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

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

Solution rapide et incorrecte: awk '/PATTERN/ {i=0} { if (i<=5) {print $0}; i+=1} BEGIN {i=6}'

0
gelraen

Aussi limité que la solution de Johnsyweb mais utilisant une approche différente et la fonctionnalité avancée de GNU awk permettant aux séparateurs d'enregistrement RegEx complets de générer un morceau de code qui, IMHO, est très awk- ish:

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

Donc, si vous voulez une solution stable qui soit également lisible, suivez la réponse de Dennis Williamson (+1 pour celle-là), mais peut-être aussi apprécierez-vous simplement la beauté de awk en regardant des lignes comme celle-ci.

0
mschilli