Как я могу использовать переменные 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


Я в замешательстве об этом.

657   8  

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/bash

Edit: как пишет "тот другой парень", это не обрабатывает обратную косую черту. Не рекомендуемый.


вы можете использовать переменную внутри 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

Кажется, что старый-добрый ENVIRON awk встроенный хэш не упоминается вообще. Пример его использования:

$ 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

или сделать его более ясным (с гораздо меньшим v s):

% 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

    Ничего не найдено.