Come si usano le variabili di shell in uno script awk?

Ho trovato alcuni modi per passare variabili di shell esterne a uno script awk, ma sono confuso su '"e"`.

Per prima cosa, ho provato con uno script di shell:

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

Poi ho provato con awk:

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

Perché c'è la differenza?

Infine ho provato questo:

$ 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 

Sono confuso su questo.

Soluzione

Getting shell variables into awk

può essere fatto in diversi modi. Alcuni sono migliori di altri. Questo dovrebbe coprire la maggior parte di essi. Se hai un commento, per favore lascia qui sotto.


Usare -v (Il modo migliore, il più portabile)

Usa l'opzione -v: (P.S. usa uno spazio dopo -v o sarà meno portabile. Per esempio, awk -v var= non awk -vvar=)

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

Questo dovrebbe essere compatibile con la maggior parte dei awk, e la variabile è disponibile anche nel blocco BEGIN:

Se hai più variabili:

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

Attenzione. Come scrive Ed Morton, le sequenze di escape saranno interpretate in modo che \t diventi un vero tab e non \t se è quello che cerchi. Può essere risolto usando ENVIRON[] o accedendovi tramite ARGV[].

PS Se ti piacciono tre barre verticali come separatore ||||, non può essere evaso, quindi usa -F"[|][|][|]"

Esempio per ottenere dati da un programma/funzione inn a awk (qui viene usata la data)

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

Variabile dopo il blocco di codice

Qui otteniamo la variabile dopo il codice awk. Questo funzionerà bene finché non avrete bisogno della variabile nel blocco BEGIN:

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

Questo funziona anche con variabili multiple awk '{print a,b,$0}' a="$var1" b="$var2" file

Usare la variabile in questo modo non funziona nel blocco BEGIN:

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

Here-string

Le variabili possono anche essere aggiunte a awk usando una [here-string][1] dalle shell che le supportano (incluso Bash):


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

Usa uno di questi a seconda di come vuoi che siano gestiti i backslash nelle variabili di shell (avar è una variabile awk, svar è una variabile di shell):

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

Vedere http://cfajohnson.com/shell/cus-faq-2.html#Q24 per dettagli e altre opzioni. Il primo metodo sopra è quasi sempre la vostra migliore opzione e ha la semantica più ovvia.

Commentari (0)

Potreste passare l'opzione command-line option -v con un nome di variabile (v) e un valore (=) della variabile d'ambiente ("${v}"):

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

O per renderlo più chiaro (con molte meno v):

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