Как я могу использовать переменные Shell в awk-скрипта?
Я нашел несколько способов передать внешние переменные оболочки к awk скрипт, но я в замешательстве о ' и ".
во-первых, я попытался с shell-скрипт:
$ 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
Я в замешательстве об этом.
8 ответов:
получение переменных оболочки в
awkможет быть сделано несколькими способами. Некоторые из них лучше, чем другие.
это лучший способ сделать это. Он использует : (P. S. используйте пробел после
-vили он будет менее портативным. Например,awk -v var=неawk -vvar=)variable="line one\nline two" awk -v var="$variable" 'BEGIN {print var}' line one line twoэто должно быть совместимо с большинств
awkи переменная доступна только вBEGINблок:несколько переменные
awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'
здесь мы получаем переменную после
awkкод. Это будет работать нормально до тех пор, пока вам не нужна переменная вBEGINблок:variable="line one\nline two" echo "input data" | awk '{print var}' var="$variable" or awk '{print var}' var="$variable" fileэто также работает с несколькими переменными
awk '{print a,b,}' a="$var1" b="$var2" file
переменная также может быть добавлена в
awkиспользуя вот строкаawk '{print }' <<< "$variable" testэто то же, что:
echo "$variable" | awk '{print }'PS, это угрожает переменной как файл вход
как верно пишут, вы можете использовать
ENVIRONпечатиEnvironmental VariablesУстановка переменной перед запуском AWK, вы можете распечатать его следующим образом:X=MyVar awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}' MyVar /bin/bashEdit: как пишет "тот другой парень", это не обрабатывает обратную косую черту. Не рекомендуемый.
вы можете использовать переменную внутри
awkкод, но это грязно и трудно читать, и какCharles Duffyуказывает, что эта версия также может быть жертвой инъекции кода. Если кто-то добавляет плохое для переменной она будет выполнена как частьawkкод.если вы хотите сделать
awkчто динамически меняется с использованием переменных, вы можете сделать это таким образом, бот не использует его для обычных переменных.variable="line one\nline two" awk 'BEGIN {print "'"$variable"'"}' line one line twoвот пример ввода кода:
variable='line one\nline two" ; for (i=1;i<=1000;++i) print i"' awk 'BEGIN {print "'"$variable"'"}' line one line two 1 2 3 . . 1000вы можете добавить много команд в
awkэтот путь. Даже сделать это сбой с недопустимыми командами.
это всегда хорошо, чтобы двойная кавычка переменной
"$variable"
Если нет, то несколько строк будут добавлены в виде длинной одной строки.пример:
var="Line one This is line two" echo $var Line one This is line two echo "$var" Line one This is line twoдругие ошибки вы можете получить без двойной кавычки:
variable="line one\nline two" awk -v var=$variable 'BEGIN {print var}' awk: cmd. line:1: one\nline awk: cmd. line:1: ^ backslash not last character on line awk: cmd. line:1: one\nline awk: cmd. line:1: ^ syntax errorи с одинарной кавычкой, он не расширяет значение переменной:
awk -v var='$variable' 'BEGIN {print var}' $variable
Кажется, что старый-добрый
ENVIRONawk встроенный хэш не упоминается вообще. Пример его использования:$ X=Solaris awk 'BEGIN{print ENVIRON["X"], ENVIRON["TERM"]}' Solaris rxvt
используйте любой из них в зависимости от того, как вы хотите обратные косые черты в переменных оболочки обрабатываются (
avar- это переменная awk,svar- это переменная оболочки):awk -v avar="$svar" '... avar ...' file awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" fileсм.http://cfajohnson.com/shell/cus-faq-2.html#Q24 для деталей и других вариантов. Первый метод выше почти всегда ваш лучший вариант и имеет наиболее очевидную семантику.
вы могли бы пройти в
-vв имя переменной (v) и значение (=) переменной среды ("${v}"):% awk -vv="${v}" 'BEGIN { print v }' 123testили сделать его более ясным (с гораздо меньшим
vs):% environment_variable=123test % awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }' 123test
вы можете использовать ARGV:
v=123test awk 'BEGIN {print ARGV[1]}' "$v"обратите внимание, что если вы собираетесь продолжать в тело, вам нужно будет настроить ARGC:
awk 'BEGIN {ARGC--} {print ARGV[2], }' file "$v"
Я должен был вставить дату в начале строк файла журнала, и это делается, как показано ниже:
DATE=$(date +"%Y-%m-%d") awk '{ print "'"$DATE"'", ; }' /path_to_log_file/log_file.logего можно перенаправить в другой файл, чтобы сохранить
Я только что изменил ответ @Jotne для "for loop".
for i in `seq 11 20`; do host myserver-$i | awk -v i="$i" '{print "myserver-"i" " }'; done
for i in chr{1..22} chrX chrY do awk -v chr="$i" '==chr' ../snp150.hg19.txt >> $chr.vcf.bed echo $i done
Comments