Piping a saída de um comando para uma variável no corpo do script awk

2

Dada inputfile

Cherries:20:100:300
Beans:12:400:500
Tomatoes:32:445:234
Potatoes:24:400:200
Kiwis:23:230:435

Eu tenho um script awk chamado testscript.script :

BEGIN{ FS = ":" 
print "------------------------"
}

if($3 + $4 > 500) {print $1, $2}
END{
print "------------------------" 
}

A saída deste script quando invocado com awk -f testscript.script inputfile é a seguinte:

------------------------
Beans 12
Tomatoes 32
Potatoes 24
Kiwis 23
------------------------

Eu quero classificar esta lista em ordem alfabética (por nome), depois armazená-la em uma variável para que esta lista seja imprimível no bloco final do script awk.

Ou seja. o código deve ser algo como isto.

BEGIN{ FS = ":" 
print "------------------------"
}

*if($3 + $4 > 500) {print $1, $2 | "sort" = variable}
END{
print "------------------------" 
print variable
}

E o comando print variable renderia

------------
------------
Beans 12
Kiwis 23
Potatoes 24
Tomatoes 32

Com a lista classificada de itens como a variável e imprimindo-a no bloco END após a linha pontilhada.

Qual é a melhor maneira de fazer isso?

    
por KMoy 02.11.2016 / 03:23

3 respostas

2

echo "---------------";awk -F: '$3+$4>500{print $1,$2}' inputfile |sort && echo "---------------"

usando o awk

awk -F: '$3+$4>500{Arr[$1]=$2}END{n=asorti(Arr,SArr);for(i=1;i<=n;i++){print SArr[i],Arr[SArr[i]]}}' inputfile
    
por 02.11.2016 / 04:20
0

Quando consideramos a melhor forma de entrar, penso no melhor caminho mais rápido para atender às minhas necessidades. Se você está tentando passar uma variável além do escopo do seu processo, eu sugiro que você distribua para um ram-drive, quase todas as distros tenham uma, então processe seu teste e canalize-o para fora desse ramdisk depois de terminar.

Em distros baseadas no Debian, você encontrará uma unidade RAM localizada em / run / shm, então algo como isto pode atender às suas necessidades.

cat inputdata.file | sed 's/:/ /g' | awk '{print $1" "$2}' | sort -k 1,1 > /run/shm/datastore.file; echo '------------------------' > datastore2.file; cat /run/shm/datastore.file>>/run/shm/datastore2.file; cat /run/shm/datastore2.file>~/destination.file

Quando a maneira como um processo deseja fazer alguma coisa está limitando você, apenas controle a formatação com lógica e uma ramdrive. Não se esqueça de mover seus dados após o processamento, pois qualquer coisa em / run / shm / * é torrada depois de reinicializar. Eu espero que isso ajude. Vou ficar de olho caso eu entenda mal o que você precisa.

    
por 02.11.2016 / 03:59
0

Você pode colocar tudo em um script e enviar a saída Awk para sort antes de ser impressa.

Supondo que você queira as linhas acima e abaixo da saída classificada (o que faz mais sentido para mim visualmente):

#!/bin/sh
printf '%s\n' ------------------------
cat "$@" | awk -F: '($3 + $4 > 500) {print $1, $2}' | sort
printf '%s\n' ------------------------

Com isso salvo em um arquivo chamado myscript definido como executável e em execução no inputfile especificado por chamada:

./myscript inputfile

A saída é semelhante a:

------------------------
Beans 12
Kiwis 23
Potatoes 24
Tomatoes 32
------------------------

Observe o uso de "$@" para que esse script possa manipular vários argumentos de arquivo, não apenas um, exatamente como o Awk pode fazer.

Você também pode pular usando cat e fazer:

awk -F: '($3 + $4 > 500) {print $1, $2}' "$@" | sort

No entanto, eu pessoalmente não gosto de passar nomes de arquivos em locais onde eles poderiam ser interpretados como código. Então eu usaria cat para concatenar os arquivos.

    
por 02.11.2016 / 06:08