Quero usar uma variável BASH dentro do AWK que é um comando AWK. Aqui está meu código de teste que pretendo tornar mais complicado se eu puder encontrar uma solução para esse problema.
exptransform=(
'print \"test\"'
)
awk -v awk_exptransform="${exptransform}" '
BEGIN{
printf ("Test.\n")
printf ("This is another test: %s\n",awk_exptransform)
awk_exptransform
}
'
Isso dá uma saída bem-sucedida para as duas primeiras linhas na declaração begin. A terceira linha não retorna nada. Como faço para que o AWK execute o conteúdo da variável como um comando?
Fiz muitas pesquisas na Internet e neste site com uma variedade de termos de pesquisa. Li a seção relevante de sed & awk (Dougherty, & Robbins, 1997). O que estou esquecendo? Isso é possível?
Aqui está o que estou tentando fazer:
cat test.txt
exptransform=(
'print $9 - $8'
'print 10^($9 - $8)'
)
for (( h=0 ; h<${#exptransform[@]} ; ++h )) ; do
awk -v awk_exptransform="${exptransform[h]}" 'BEGIN{FS = "\t"} {if ( $4~/1/ && $5~/2/ && $6~/1/ && $7~/1/ && $2!~/20160630_0609/ && $2!~/20170208_2324/ && $2!~/20160804_0635/) awk_exptransform}' test.txt
done
Saída desejada:
subject run day_1_date include night tone_delivered sleep_arousal tone_1 tone_n
00105 20170413_0406 20170411 1 2 1 1 70 105
00105 20170413_0535 20170411 1 2 1 1 70 70
35
0
99999999999999996863366107917975552
1
Produção real:
subject run day_1_date include night tone_delivered sleep_arousal tone_1 tone_n
00105 20170413_0406 20170411 1 2 1 1 70 105
00105 20170413_0535 20170411 1 2 1 1 70 70
Sinceramente,
Dante Picchioni
Uma opção seria:
awk
chamada com várias-f
bandeirasConsiderar:
A chamada atual do OP
awk
agora se tornará:Se estiver usando,
GNU awk
você pode usar os arquivos 'include', que funcionam de maneira semelhante, mas com um método integrado para referenciar sua própria biblioteca deawk
scripts.Existem algumas maneiras de fatiar e cortar isso...
Usando o
-i
sinalizador de linha de comando:Usando o
@include
comando dentro do script principal:Ou chamando diretamente de um
awk
script inline:Usando as ideias acima, podemos chegar a uma solução mais "dinâmica", na qual o OP designa um arquivo de função apropriado, garantindo que todos esses arquivos definam uma função com o mesmo nome, por exemplo:
Usando a
-f
opção para designar o arquivo de função desejado:Usando a
GNU awk / include file
abordagem:Veja GNU awk: Incluir arquivos para uma breve introdução ao uso do
@include
.Veja GNU awk: variável AWKPATH para uma introdução ao uso
AWKPATH
para referenciar um ou mais diretórios de arquivos de inclusão personalizados.Em relação a "Como faço para que o AWK execute o conteúdo da variável como um comando?" - você não pode. Bem, não diretamente, de qualquer forma, pois o awk não tem um
eval
comando como o shell. Você pode implementar sua própria versão deeval
, por exemplo, veja how-to-coerce-awk-to-evaluate-string-as-math-expression , mas parece que é isso que você está realmente tentando fazer, usando qualquer awk:ou talvez isto:
mas se você implementar
eval
ou deixar que variáveis/funções do shell se expandam para se tornarem parte do corpo de um script awk antes que o awk o veja como acima, isso é quase certamente uma péssima ideia. Por favor, poste uma nova pergunta sobre o que você quer fazer em vez de como você está tentando fazer para que possamos ajudá-lo.Você sempre pode fazer:
Isso incorpora a expansão da variável shell no
awk
código e também a exporta como uma variável de ambiente para queawk
seja possível recuperá-la e imprimi-la.A propósito, você quer evitar
-v
passar texto arbitrário,awk
pois isso confunde as barras invertidas, pois os valores estão sujeitos a expansões\n
,\b
,\123
...Para uma matriz desses
awk
trechos de código, pode ser melhor gerar o código dinamicamente:O que dá:
Mostrando ao OP como a atualização mais recente pode ser implementada com as respostas já fornecidas...
Modificando o loop atual do OP
bash / while
para cortar e colarbash
entradas de array no meio de umawk
script:NOTA: não há necessidade de uma
-v variable=value
cláusulaIsso gera:
Usando uma
awk
função para incorporar as operações desejadas:Se descomentarmos a primeira entrada na
main.awk
chamada se tornará:NOTA: se estiver usando
GNU awk
(compilado com bibliotecas GNU MPFR/MP), podemos adicionar o-M/--bignum
sinalizador para fornecer maior precisão aritmética, por exemplo: