Hoe gebruik ik shell variabelen in een awk script?

Ik heb wat manieren gevonden om externe shell variabelen door te geven aan een awk script, maar ik'ben verward over ' en ".

Eerst probeerde ik het met een shell script:

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

Daarna probeerde ik het met awk:

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

Waarom is het verschil?

Als laatste heb ik dit geprobeerd:

$ 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 

Ik ben verward over dit.

Oplossing

Shell variabelen in awk krijgen

kan op verschillende manieren gedaan worden. Sommige zijn beter dan andere. Dit zou de meeste moeten behandelen. Als je een opmerking hebt, laat die dan hieronder achter.


Het gebruik van -v (De beste manier, meest portable)

Gebruik de -v optie: (P.S. gebruik een spatie na -v of het zal minder portable zijn. Bijv. awk -v var= niet awk -vvar=)

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

Dit zou compatibel moeten zijn met de meeste awk, en de variabele is ook beschikbaar in het BEGIN blok:

Als je meerdere variabelen hebt:

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

Waarschuwing. Zoals Ed Morton schrijft, escape sequenties worden geïnterpreteerd zodat tab een echte tab wordt en niet tab als dat is waar je naar zoekt. Kan worden opgelost door ENVIRON[] te gebruiken of het via ARGV[] te benaderen

PS Als je drie verticale streepjes als scheidingsteken || wilt, kan dat niet ge-escaped worden, dus gebruik -F"[|][|][|]"

Voorbeeld van het ophalen van gegevens uit een programma/functie in awk (hier wordt datum gebruikt)

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

Variabele na code blok

Hier krijgen we de variabele na de awk code. Dit werkt prima, zolang je de variabele niet nodig hebt in het BEGIN blok:

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

Dit werkt ook met meerdere variabelen awk '{print a,b,$0}' a="$var1" b="$var2" bestand

Variabele op deze manier gebruiken werkt niet in BEGIN blok:

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

Here-string

Variabelen kunnen ook worden toegevoegd aan awk met behulp van een [here-string][1] van shells die dat ondersteunen (inclusief Bash):


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

Gebruik een van deze, afhankelijk van hoe u wilt dat backslashes in de shell variabelen worden behandeld (avar is een awk variabele, svar is een shell variabele):

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

Zie http://cfajohnson.com/shell/cus-faq-2.html#Q24 voor details en andere opties. De eerste methode hierboven is bijna altijd je beste optie en heeft de meest voor de hand liggende semantiek.

Commentaren (0)

Je zou de command-line optie -v kunnen doorgeven met een variabelenaam (v) en een waarde (=) van de omgevingsvariabele ("${v}"):

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

Of om het duidelijker te maken (met veel minder vs):

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