
Ich habe mehrere .dat-Dateien (variabel) mit jeweils zwei Informationen darin, einem Gewicht und einer Größe, durch Leerzeichen getrennt, wie folgt, wobei „Vorname_Nachname“ ein Name ist:
18kg 1.2m
in „Vorname1_Nachname1.dat“
12kg 1.6m
in "First2_Last2.dat" usw.
Ich muss sie entweder nach dem ersten oder dem zweiten Wert in jeder Datei sortieren. Ich denke, ich muss cat
alle Dateien kombinieren, die Einheiten mit einem entfernen cut
(bin mir da nicht so sicher), dann die Dateinamen als dritte Spalte hinzufügen paste
und schließlich sort -k 1,1 temp.txt
in meiner temporären Datei, um die gewünschte Ausgabe zu erhalten und dabei immer noch verfolgen zu können, aus welcher Datei jeder Wert stammt, weil ich die zugehörigen Namen brauche, um anschließend für jede Person eine andere Datei in der richtigen Reihenfolge zu öffnen. Meine Ausgabedatei, die ich verwenden würde, würde also ungefähr so aussehen:
12 1.6 First2_Last2.dat
18 1.2 First1_Last1.dat
Ich frage mich, ob es dafür eine bessere Möglichkeit gibt, etwas Integriertes oder eine Eigenschaft des .dat-Dateityps zu verwenden, die mir fehlt. Oder vielleicht mit awk
?
Antwort1
grep
Mit und können Sie sed
den Sortierschlüssel extrahieren und nur bestimmte Spalten zum Sortieren angeben:
grep -H kg *.dat \
| sed 's/^\([^:]\+\):\([0-9.]\+\)kg \+\([0-9.]\+\)m.*$/\2 \3 \1/' \
| sort -t' ' -k1,2 -g
Beispielausgabe:
12 1.6 First2_Last2.dat
18 1.2 First1_Last1.dat
Antwort2
Wenn Ihre Dateien jeweils nur ein Datum (eine Zeile) enthalten, könnte etwas so Einfaches wie das Folgende funktionieren:
for x in *.dat ; do
echo $(< "$x") $x # print contents of file and add the filename
done | sort -nsk2,2 # stable sort by the second column.
Ich habe einen schnellen Test mit GNU sort durchgeführt und konnte nicht wirklich feststellen, dass die Einheiten oder Dezimalstellen Probleme verursachten, aber ich gebe keine Garantien.
Antwort3
Vielleicht mit (einer aktuellen Version von) GNU awk – vorausgesetzt, dass Sie mit „.dat-Datei“ lediglich eine durch Leerzeichen getrennte Textdatei meinen:
awk -v sort=2 '
{
gsub(/kg|m/,"",$0);
a[$sort]=$0 FS FILENAME;
}
END {
PROCINFO["sorted_in"]="@ind_num_asc";
for (i in a) print a[i];
}' *.dat
wobei die Variable sort
die Spalte festlegt, nach der sortiert werden soll ( 1
oder 2
); oder als Einzeiler
awk -v sort=1 '{gsub(/kg|m/,"",$0); a[$sort]=$0 FS FILENAME}; END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a) print a[i]}' *.dat
Testen
$ awk -v sort=1 '{gsub(/kg|m/,"",$0); a[$sort]=$0 FS FILENAME}; END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a) print a[i]}' *.dat
12 1.6 First2_Last2.dat
18 1.2 First1_Last1.dat
Und
$ awk -v sort=2 '{gsub(/kg|m/,"",$0); a[$sort]=$0 FS FILENAME}; END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a) print a[i]}' *.dat
18 1.2 First1_Last1.dat
12 1.6 First2_Last2.dat