Weiterleiten der Ausgabe eines Befehls an eine Variable im Hauptteil eines Awk-Skripts

Weiterleiten der Ausgabe eines Befehls an eine Variable im Hauptteil eines Awk-Skripts

Gegebeninputfile

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

Ich habe ein Awk-Skript mit dem Namen testscript.script:

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

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

Die Ausgabe dieses Skripts beim Aufrufen awk -f testscript.script inputfilelautet wie folgt:

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

Ich möchte diese Liste alphabetisch (nach Namen) sortieren und sie dann in einer Variablen speichern, so dass diese Liste imEndblockdes Awk-Skripts.

Der Code sollte also ungefähr so ​​aussehen.

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

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

Und der print variableBefehl würde nachgeben

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

Mit der sortierten Liste der Elemente als Variable und Drucken im END-Block nach der gepunkteten Linie.

Wie lässt sich dies am besten bewerkstelligen?

Antwort1

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

mit 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

Antwort2

Wenn man über den „besten“ Weg nachdenkt, muss man viel beachten. Ich denke, der beste Weg ist der schnellste, der meinen Anforderungen entspricht. Wenn Sie versuchen, eine Variable zu übergeben, die über den Umfang Ihres Prozesses hinausgeht, würde ich vorschlagen, sie auf ein RAM-Laufwerk zu leiten (fast alle Distributionen haben eines), dann Ihren Test auszuführen und sie von diesem RAM-Laufwerk aus zu leiten, wenn Sie fertig sind.

Bei Debian-basierten Distributionen befindet sich ein RAM-Laufwerk unter /run/shm, also könnte so etwas Ihren Anforderungen entsprechen.

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

Wenn Sie durch die Art und Weise, wie ein Prozess etwas tun möchte, eingeschränkt werden, steuern Sie die Formatierung einfach mit Logik und einem RAM-Laufwerk. Vergessen Sie nicht, Ihre Daten nach der Verarbeitung zu verschieben, da alles in /run/shm/* nach dem Neustart hinüber ist. Ich hoffe, das hilft. Ich werde ein Auge darauf haben, falls ich missverstanden habe, was Sie brauchen.

Antwort3

Du kannststecke das Ganze in ein Shell-Skriptund leiten Sie die Awk-Ausgabe weiter, sortbevor sie gedruckt wird.

Angenommen, Sie möchten die Zeilen über und unter der sortierten Ausgabe (was für mich optisch mehr Sinn macht):

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

Dies wird in einer Datei namens „ myscriptset to executable“ gespeichert und auf dem inputfilevon Ihnen angegebenen Computer ausgeführt, indem Sie Folgendes aufrufen:

./myscript inputfile

Die Ausgabe sieht wie folgt aus:

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

Beachten Sie die Verwendung, "$@"damit dieses Skript mehrere Dateiargumente verarbeiten kann, nicht nur eines, genau wie Awk.

Sie können die Verwendung auch überspringen catund einfach Folgendes tun:

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

Ich persönlich mag es jedoch nicht, Dateinamen an Stellen weiterzugeben, an denen siekönnteals Code interpretiert werden. Daher würde ich verwenden, catum die Dateien zu verketten.

verwandte Informationen