Eu tenho um arquivo de dados que eu quero normalizar usando awk
, com base no último ponto de dados. Portanto, eu gostaria de acessar o último ponto de dados primeiro, normalizar os dados e depois processar normalmente.
O método a seguir, usando tac
duas vezes, faz o trabalho, mas talvez seja mais complicado que o necessário.
$ cat file
0 5
1 2
2 3
3 4
$ tac file | awk 'NR==1{norm=$2} {print $1, $2/norm}' | tac
0 1.25
1 0.5
2 0.75
3 1
Minha pergunta é a seguinte: É possível obter o resultado acima usando apenas o awk?
Acho que a resposta é "Não, o awk verifica o arquivo linha por linha", mas estou aberto a sugestões de alternativas.
fonte
$ awk --version GNU Awk 3.1.8
. Você pode talvez adicionar uma explicação muito pequena sobre como são tratados dois arquivos de entrada e o quenext
faz?Se sua fonte de dados é um arquivo que pode ser lido várias vezes (ou seja, não é um fluxo), você deve primeiro usar
tail(1)
para obter os dados que deseja da última linha e passar para awk para o processamento seqüencial do arquivo.tail
procurará o final do arquivo para ler a última linha sem precisar ler todos os dados anteriores.Isso será uma grande conquista para arquivos grandes, nos quais o arquivo inteiro não caberá no cache do buffer (o que significa que precisaria ser lido do disco duas vezes, uma vez para cada passagem) e ajudará em menor grau por não precisar verificar a entrada para chegar à última linha. Arquivos menores podem não mostrar muita diferença em uma abordagem de duas passagens.
fonte
Você pode carregá-los em uma matriz e lê-la ao contrário:
Você poderia fazê-lo com mais eficiência, mas esse tipo de ilustração
awk
mostra por que não é a ferramenta certa para isso. Continue usandotac
onde estiver disponível, o GNU tac é geralmente o mais rápido de uma variedade de ferramentas para este trabalho.fonte
for
loop noawk
não é a solução.