2012-10-23 1 views
5

Ich habe eine einfache awk-Einlage, die die nächste Zeile auf die aktuelle Zeile faltet, wenn ein bestimmtes Muster übereinstimmt. Hier ist sie:Wie wirkt sich eine nachgestellte Zahl auf den Körper eines awk-Skripts aus?

awk '/two/ { printf $1; next; } 1' test.txt 

mit folgender Eingabe:

one 
two 
three 
four 
five 
six 

one 
two 
three 
four 

Sie erhalten:

one 
twothree 
four 
five 
six 

one 
twothree 
four 

Beachten Sie, dass die "drei" mit der "zwei" zusammengeklappt, was was ist Ich wollte auftreten. Ich fand diese Lösung (erinnere mich nicht wo) und fand es merkwürdig, dass die nachlaufende "1" das fehlende Teil zu sein schien, das den gewünschten Effekt ergab. Wenn Sie es herausnehmen, erhalten Sie:

awk '/two/ { printf $1; next; }' test.txt 
twotwo 

Als Ergebnis. Meine Frage ist also, was macht die abschließende '1' und wo ist sie dokumentiert?

Danke!

Antwort

6

Für awk, 1 bedeutet wahr, und wenn ein Ausdruck wahr ist, awk die aktuelle Zeile standardmäßig drucken.

Beispiele:

  • awk '1' /etc/passwd wird die gesamte Datei drucken
  • awk '0' /etc/passwd wird nicht drucken die gesamte Datei

Wenn Sie in der Arithmetik gut sind (oder Sie haben Phantasie oder Programmierung Fähigkeiten), gibt es viele Tricks, die Sie mit diesem Verhalten tun können.

3

"Die '1' am Ende des ganzen Awk-Einstrichs druckt die modifizierte Zeile aus (es ist syntaktischer Zucker für nur" Print "(das selbst ist syntaktischer Zucker für" print $ 0 "))).

-catonmat

+0

Ah! Danke für den Link. Sehr hilfreich. – drsnyder

1

Sie haben Ihre Antwort auf Ihre Frage, aber Ihr Skript geschrieben ist unsicher. Das erste Argument für printf ist eine Formatzeichenfolge, keine Daten. Sie können es manchmal verwenden, um Daten zu drucken, aber nur wenn es in Ihrem Skript fest codiert ist, nicht wenn Sie es aus der Eingabe lesen. Schauen Sie, was passiert, wenn Sie Ihre Eingabe geschieht eine printf Formatierungszeichenfolge enthalten:

$ cat file 
one 
two%s 
three 
four 

$ awk '/two/ { printf $1; next; } 1' file 
one 
awk: cmd. line:1: (FILENAME=file2 FNR=2) fatal: not enough arguments to satisfy format string 
     `two%s' 
      ^ran out for this one 

Der richtige Weg, um das Skript zu schreiben ist:

$ awk '/two/ { printf "%s",$1; next; } 1' file 
one 
two%sthree 
four