Canalizar la salida de un comando a una variable en el cuerpo del script awk

Canalizar la salida de un comando a una variable en el cuerpo del script awk

Dadoinputfile

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

Tengo un script awk, llamado testscript.script:

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

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

El resultado de este script cuando se invoca awk -f testscript.script inputfilees el siguiente:

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

Quiero ordenar esta lista alfabéticamente (por nombre) y luego almacenarla en una variable para que esta lista se pueda imprimir en elbloque finaldel script awk.

Es decir, el código debería verse así.

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

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

Y el print variablecomando cedería

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

Con la lista ordenada de elementos como variable e imprimiéndola en el bloque FINAL después de la línea de puntos.

¿Cuál es la mejor manera de hacer esto?

Respuesta1

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

usando 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

Respuesta2

Al considerar la "mejor" forma, hay muchas cosas en juego, pienso en la mejor como la ruta más rápida que satisface mis necesidades. Si está intentando pasar una variable más allá del alcance de su proceso, le sugeriría conectarla a una unidad RAM, casi todas las distribuciones tienen una, luego procesar su prueba y salir de ese disco RAM una vez que haya terminado.

En las distribuciones basadas en Debian, encontrará una unidad RAM ubicada en /run/shm, por lo que algo como esto podría satisfacer sus necesidades.

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

Cuando la forma en que un proceso quiere hacer algo te limita, simplemente controla el formateo con lógica y una memoria RAM. No olvide mover sus datos después de procesarlos, ya que todo lo que esté en /run/shm/* se eliminará una vez que reinicie. Espero que esto ayude. Estaré atento en caso de que no haya entendido bien lo que necesitas.

Respuesta3

Puedepegue todo en un script de shelly canalice la salida de Awk sortantes de que se imprima.

Suponiendo que desea las líneas encima y debajo de la salida ordenada (lo que tiene más sentido para mí visualmente):

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

Con esto guardado en un archivo llamado myscriptset to ejecutable, y ejecutándose en el que inputfileusted especificó llamando a:

./myscript inputfile

La salida se parece a:

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

Tenga en cuenta el uso de "$@"para que este script pueda manejar múltiples argumentos de archivo, no solo uno, tal como lo puede hacer Awk.

También puedes omitir el uso caty simplemente hacer:

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

Sin embargo, personalmente no me gusta pasar nombres de archivos en lugares dondepodríaser interpretado como código. Entonces lo usaría catpara concatenar los archivos.

información relacionada