Как да използвам променливи на обвивката в awk скрипт?
Намерих няколко начина за предаване на външни променливи на shell към скрипт awk
, но съм объркан относно '
и "
.
Първо опитах с шел скрипт:
$ v=123test
$ echo $v
123test
$ echo "$v"
123test
След това опитах с awk:
$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123
Защо е разликата?
Накрая опитах това:
$ 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
Объркан съм от това.
258
3
Използване на
-v
(Най-добрият начин, най-преносимият)Използвайте опцията
-v
: (P.S. Използвайте интервал след-v
, иначе ще бъде по-малко преносимо. Например,awk -v var=
, а неawk -vvar=
)Това би трябвало да е съвместимо с повечето
awk
, а променливата е достъпна и в блокаBEGIN
:Ако имате няколко променливи:
Предупреждение. Както пише Ед Мортън, ескейп последователностите ще бъдат интерпретирани, така че
\t
ще се превърне в истинскиtab
, а не\t
, ако това е, което търсите. Може да се реши с помощта наENVIRON[]
или да се получи достъп чрезARGV[]
PS Ако искате да използвате три вертикални чертички като разделител
||||
, те не могат да бъдат избягнати, затова използвайте-F"[|][|][|][|]"
Променлива след блока с код
Тук получаваме променливата след кода
awk
. Това ще работи добре, стига да не се нуждаете от променливата в блокаBEGIN
:Това работи и с множество променливи
awk '{print a,b,$0}' a="$var1" b="$var2" file
Използването на променлива по този начин не работи в блок
BEGIN
:Here-string
Променливата може да бъде добавена към
awk
и с помощта на [here-string][1] от шеловете, които ги поддържат (включително Bash):Използвайте някоя от тях в зависимост от това как искате да се обработват обратните наклонени черти в променливите на обвивката (
avar
е променлива на awk,svar
е променлива на обвивката):Вижте http://cfajohnson.com/shell/cus-faq-2.html#Q24 за подробности и други опции. Първият метод по-горе почти винаги е най-добрият вариант и има най-очевидна семантика.
Можете да подадете опцията на командния ред
-v
с име на променлива (v
) и стойност (=
) на променливата на средата ("${v}"
):Или, за да стане по-ясно (с много по-малко
v
):