Como usar variáveis shell em um script awk?

Eu encontrei algumas maneiras de passar variáveis shell externas para um script awk', mas I'm confuso sobre'e"`.

Primeiro, tentei com um guião de concha:

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

Depois tentou awk:

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

Porque é que a diferença?

Por fim, tentei isto:

$ 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 

I'estou confuso com isto.

Solução

Conhecendo variáveis shell em `awk'.

pode ser feito de várias maneiras. Algumas são melhores do que outras. Isto deve cobrir a maioria delas. Se você tem algum comentário, por favor, saia abaixo.


Using -v (A melhor maneira, a mais portátil)

Utilize a opção -v': (P.S. utilize um espaço após o-v' ou será menos portátil. Por exemplo, awk -v var= não awk -vvar=)

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

Isto deve ser compatível com a maioria dos awk, e a variável também está disponível no bloco BEGIN:

Se você tiver múltiplas variáveis:

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

**Aviso***. Como Ed Morton escreve, as seqüências de fuga serão interpretadas de modo que "não" se torne uma verdadeira "tabulação" e não "não", se é isso que você procura. Pode ser resolvido utilizando ENVIRON[] ou acessando-o através de ARGV[]

**PS*** Se você gosta de três barras verticais como separador ||||, ele pode't ser escapado, então use -F"[|][|][|][|]"

Exemplo de como obter dados de um programa/função da pousada para awk (aqui a data é utilizada)

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

Variável após bloco de código

Aqui obtemos a variável após o código 'awk'. Isto vai funcionar bem desde que você não precise da variável no bloco BEGIN:

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

Isto também funciona com múltiplas variáveis awk '{impressão a,b,$0}' a="$var1" b="$var2" file

Utilizar a variável desta forma não funciona no bloco BEGIN:

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

Sua corda

A variável também pode ser adicionada ao awk utilizando um [aqui [aqui][1] de shells que as suportam (incluindo o Bash):


awk '{print $0}' 
Comentários (6)

Utilize qualquer uma destas dependendo de como você quer que as barras invertidas nas variáveis da shell sejam tratadas (avar é uma variável awk, svar é uma variável da shell):

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

Veja http://cfajohnson.com/shell/cus-faq-2.html#Q24 para detalhes e outras opções. O primeiro método acima é quase sempre a sua melhor opção e tem a semântica mais óbvia.

Comentários (0)

Você poderia passar na opção de linha de comando -v com um nome de variável (v) e um valor (=) da variável de ambiente ("${v}"):

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

Ou para torná-lo mais claro (com muito menos vs):

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