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

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

Dadoinputfile

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 awk -f testscript.script inputfileé a seguinte:

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

Quero classificar esta lista em ordem alfabética (por nome) e armazená-la em uma variável para que esta lista possa ser impressa nobloco finaldo script awk.

Ou seja, o código deve ser parecido com isto.

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

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

E o print variablecomando renderia

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

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

Qual é a melhor maneira de fazer isso?

Responder1

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

Responder2

Ao considerar a 'Melhor' maneira, há muitas coisas em jogo, penso na melhor rota como a mais rápida que atende às minhas necessidades. Se você estiver tentando passar uma variável além do escopo do seu processo, sugiro canalizá-la para um ram-drive, quase todas as distros têm um, então processe seu teste e saia desse ramdisk depois de terminar.

Nas 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 forma como um processo quer fazer algo está te limitando, basta controlar a formatação com lógica e um ramdrive. Não se esqueça de mover seus dados após o processamento, pois qualquer coisa em /run/shm/* é torrada quando você reinicia. Eu espero que isso ajude. Ficarei de olho caso eu tenha entendido mal o que você precisa.

Responder3

Você podecole tudo em um script de shelle canalize a saída do Awk sortantes 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 myscriptset to executável e executando no que inputfilevocê especificou chamando:

./myscript inputfile

A saída é semelhante a:

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

Observe o uso de "$@"para que este script possa lidar com vários argumentos de arquivo, não apenas um, da mesma forma que o Awk pode fazer.

Você também pode pular o uso cate apenas 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 elespoderiaser interpretado como código. Então eu usaria catpara concatenar os arquivos.

informação relacionada