Wie verwende ich Shell-Variablen in einem awk-Skript?

Ich habe einige Möglichkeiten gefunden, externe Shell-Variablen an ein awk-Skript zu übergeben, aber ich bin verwirrt über ' und ".

Zuerst habe ich es mit einem Shell-Skript versucht:

$ v=123test
$ echo $v
123test
$ echo "$v"
123test

Dann versuchte ich es mit awk:

$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123

Worin besteht der Unterschied?

Zuletzt habe ich dies versucht:

$ awk 'BEGIN{print " '$v' "}'
$  123test
$ awk 'BEGIN{print ' "$v" '}'
awk: cmd. line:1: BEGIN{print
awk: cmd. line:1:             ^ unexpected newline or end of string 

Ich bin darüber verwirrt.

Lösung

Shell-Variablen in awk setzen

kann auf verschiedene Arten erfolgen. Einige sind besser als andere. Dies sollte die meisten von ihnen abdecken. Wenn Sie einen Kommentar haben, hinterlassen Sie ihn bitte unten.


Verwendung von -v (Der beste Weg, am besten portabel)

Benutzen Sie die -v Option: (P.S. Benutzen Sie ein Leerzeichen nach -v oder es wird weniger portabel sein. Z.B., awk -v var= nicht awk -vvar=)

variable="line one\nline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two

Dies sollte mit den meisten awk kompatibel sein, und die Variable ist auch im BEGIN-Block verfügbar:

Wenn Sie mehrere Variablen haben:

awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'

Warnung. Wie Ed Morton schreibt, werden Escape-Sequenzen interpretiert, so dass \t zu einem echten tab wird und nicht zu \t, wenn das das ist, wonach Sie suchen. Kann durch die Verwendung von ENVIRON[] oder den Zugriff über ARGV[] gelöst werden.

PS Wenn Sie drei senkrechte Striche als Trennzeichen ||| mögen, können diese nicht escaped werden, also verwenden Sie -F"[|][|][|][|]"

Beispiel für das Abrufen von Daten aus einem Programm/Funktion inn to awk (hier wird das Datum verwendet)

awk -v time="$(date +"%F %H:%M" -d '-1 minute')" 'BEGIN {print time}'

Variable nach Code-Block

Hier bekommen wir die Variable nach dem awk Code. Das funktioniert gut, solange man die Variable nicht im BEGIN-Block braucht:

variable="line one\nline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file

Dies funktioniert auch mit mehreren Variablen awk '{print a,b,$0}' a="$var1" b="$var2" file`

Die Verwendung von Variablen auf diese Weise funktioniert nicht im BEGIN-Block:

echo "input data" | awk 'BEGIN {print var}' var="${variable}"

Hier-Zeichenfolge

Variable können auch zu awk hinzugefügt werden, indem man einen [here-string][1] von Shells benutzt, die sie unterstützen (einschließlich Bash):


awk '{print $0}' 
Kommentare (6)

Verwenden Sie eine der beiden, je nachdem, wie Sie Backslashes in den Shell-Variablen behandeln wollen (avar ist eine awk-Variable, svar ist eine Shell-Variable):

awk -v avar="$svar" '... avar ...' file
awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" file

Siehe http://cfajohnson.com/shell/cus-faq-2.html#Q24 für Details und andere Optionen. Die erste Methode oben ist fast immer die beste Option und hat die offensichtlichste Semantik.

Kommentare (0)

Sie können die Befehlszeilenoption -v mit einem Variablennamen (v) und einem Wert (=) der Umgebungsvariablen ("${v}") übergeben:

% awk -vv="${v}" 'BEGIN { print v }'
123test

Oder um es deutlicher zu machen (mit viel weniger v):

% environment_variable=123test
% awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }'
123test
Kommentare (0)