Passando vars para awk

1

Eu tenho um arquivo enorme que precisa ser dividido em vários arquivos.

Estou usando split , que está funcionando bem

file=home/sap/dim/deltafile.D2017313.T100058932IDL.gz

gunzip -c ${file} | split -l 10000000 -d -a 4 - ${file%/*}/"working".$v_procid.'basename ${file%.*}'.part.

Com awk , também está funcionando. Mas quando eu passar a variável awk , ela está falhando.

gunzip -c ${file} | awk 'NR%10000000==1 {x="F" ++i} {print > x}'  

awk cria arquivos com o nome F1 , F2 ...

Eu preciso disso usando variáveis e tentei todos os exemplos diferentes. Sem sorte.

    
por mcky mini 25.01.2018 / 16:57

3 respostas

3

Você pode passar dados para awk com -v var=value , qualquer número de opções -v pode estar presente:

awk -v foo=FOO 'END {print foo}' </dev/null
awk -v foo=FOO -v bar=BAR 'END {print foo, bar}' </dev/null

Como de costume, você também pode usar variáveis do shell, etc. como parte da tarefa:

awk -v bar="$PWD" 'END {print bar}' </dev/null

file=home/sap/dim/deltafile.D2017313.T100058932IDL.gz
awk -v bar="${file%/*}" 'END {print bar}' </dev/null
    
por 26.01.2018 / 06:39
3

Construa a parte estática do nome do arquivo fora de awk e passe-a para uma variável awk :

prefix="${file%/*}/working.$v_procid.$(basename ${file%.*}).part"

gunzip -c "$file" |
awk -v p="$prefix" 'NR % 10000000 == 1 { f = p "" ++i } { print >f }'

O f = p "" ++i bit pode ser substituído por f = sprintf("%s%s", p, ++i) .

Se você espera gerar um grande número de arquivos de saída, convém explicitamente close() o arquivo anterior antes de gravar no próximo arquivo de saída, para que você não execute acidentalmente os descritores de arquivos disponíveis:

awk -v p="$prefix" 'NR % 10000000 == 1 { if (f) close(f); f = p "" ++i } { print >f }'
    
por 26.01.2018 / 08:50
1

Outro ponto para adicionar às duas respostas anteriores. Existe uma segunda maneira de passar variáveis, adicionando-as à linha de comando depois que o programa foi especificado.

awk program.awk /path/to/input var=value second/input

Do manual do GNU Awk

The distinction between file name arguments and variable-assignment arguments is made when awk is about to open the next input file. At that point in execution, it checks the file name to see whether it is really a variable assignment; if so, awk sets the variable instead of reading a file.

Therefore, the variables actually receive the given values after all previously specified files have been read. In particular, the values of variables assigned in this fashion are not available inside a BEGIN rule (see BEGIN/END), because such rules are run before awk begins scanning the argument list.

Então, enquanto

awk -v var=value program.awk

permite que você passe valores para o início do programa, antes de qualquer parte BEGIN, você também pode alterar as variáveis do programa, se for necessário.

    
por 28.01.2018 / 00:35