Eu encontrei algumas maneiras de passar variáveis externas do shell para um awk
script, mas estou confuso sobre '
e "
.
Primeiro, tentei com um script de shell:
$ v=123test
$ echo $v
123test
$ echo "$v"
123test
Então tentei o awk:
$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123
Por que a diferença?
Por fim, tentei o seguinte:
$ 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
Estou confuso sobre isso.
/var/
. Em vez disso, use til:awk -v var="$var" '$0 ~ var'
Respostas:
Usando
-v
(da melhor maneira, mais portátil)Use a
-v
opção: (PS use um espaço depois-v
ou será menos portátil. Por exemplo,awk -v var=
nãoawk -vvar=
)Isso deve ser compatível com a maioria
awk
e a variável também está disponível noBEGIN
bloco:Se você tiver várias variáveis:
Atenção . Como escreve Ed Morton, as seqüências de escape serão interpretadas para que
\t
se tornem reaistab
e não\t
se é isso que você procura. Pode ser resolvido usandoENVIRON[]
ou acessando-o viaARGV[]
PS Se você gosta de três barras verticais como separador
|||
, elas não podem ser escapadas, então use-F"[|][|][|]"
Variável após bloco de código
Aqui nós obtemos a variável após o
awk
código. Isso funcionará bem, desde que você não precise da variável noBEGIN
bloco:awk '{print a,b,$0}' a="$var1" b="$var2" file
FS
para cada arquivo.awk 'some code' FS=',' file1.txt FS=';' file2.ext
BEGIN
bloco:echo "input data" | awk 'BEGIN {print var}' var="${variable}"
Here-string
A variável também pode ser adicionada ao
awk
uso de uma string here de shells que os suportam (incluindo o Bash):É o mesmo que:
PS trata a variável como uma entrada de arquivo.
ENVIRON
entradaEnquanto o TrueY escreve, você pode usar o
ENVIRON
para imprimir variáveis de ambiente . Definindo uma variável antes de executar o AWK, você pode imprimi-la assim:ARGV
entradaComo escreve Steven Penny, você pode usar
ARGV
para colocar os dados no awk:Para inserir os dados no próprio código, não apenas o BEGIN:
Variável dentro do código: USE COM CUIDADO
Você pode usar uma variável dentro do
awk
código, mas é confuso e difícil de ler e, comoCharles Duffy
aponta, esta versão também pode ser vítima de injeção de código. Se alguém adicionar coisas ruins à variável, ela será executada como parte doawk
código.Isso funciona extraindo a variável dentro do código, tornando-se parte dela.
Se você deseja fazer uma
awk
alteração dinâmica dinamicamente com o uso de variáveis, pode fazê-lo desta maneira, mas NÃO o use para variáveis normais.Aqui está um exemplo de injeção de código:
Você pode adicionar muitos comandos
awk
dessa maneira. Até mesmo travar com comandos não válidos.Informação extra:
Uso de aspas duplas
É sempre bom fazer aspas duplas.
"$variable"
Caso contrário, várias linhas serão adicionadas como uma única linha longa.
Exemplo:
Outros erros que você pode obter sem aspas:
E com aspas simples, ele não expande o valor da variável:
Mais informações sobre AWK e variáveis
Leia este FAQ .
fonte
awk -v repo="$1" -v tag="$2" 'BEGIN {print "repo="repo,"tag="tag}'
. Verá se imprime a variável. Poste uma pergunta, se você não conseguir descobrir.Parece que o bom e velho
ENVIRON
awko hash embutido não é mencionado. Um exemplo de seu uso:fonte
-v
não funciona quando o valor contém barras invertidas.awk -v x='\c\d' ...
então ele será usado corretamente. Mas quandox
é impresso awk deixa cair a famosa:awk: warning: escape sequence '\c' treated as plain 'c'
mensagem de erro ... Obrigado!-v
foi assim que foi projetado para funcionar, para que você possa usar\t
a variável e corresponder a uma guia literal nos dados, por exemplo. Se esse não é o comportamento que você deseja, não-v
o usaARGV[]
ouENVIRON[]
.Use qualquer um destes, dependendo de como você deseja manipular barras invertidas nas variáveis do shell (
avar
é uma variável awk,svar
é uma variável do shell):Consulte http://cfajohnson.com/shell/cus-faq-2.html#Q24 para obter detalhes e outras opções. O primeiro método acima é quase sempre sua melhor opção e possui a semântica mais óbvia.
fonte
Você pode 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}"
):Ou, para torná-lo mais claro (com muito menos
v
s):fonte
Você pode utilizar o ARGV:
Observe que, se você continuar no corpo, precisará ajustar o ARGC:
fonte
Acabei de alterar a resposta de @ Jotne para "for loop".
fonte
-v
opção do Awk, que já foi mencionada em muitas das respostas existentes. Se você deseja mostrar como executar o Awk em um loop, essa é realmente uma pergunta diferente.Eu tive que inserir a data no início das linhas de um arquivo de log e é feito como abaixo:
Pode ser redirecionado para outro arquivo para salvar
fonte