Ich habe eine Textdatei wie diese
foo bar baz
1 a alpha
2 b beta
3 c gamma
Ich kann awk verwenden, um bestimmte Spalten, wie 1 und 3, mit zu drucken {print $1, $3}
, aber ich möchte die zu druckenden Spalten angeben, indem ich stattdessen die Spaltenüberschrift angebe, etwa wie {print $foo, $baz}
. Das ist nützlich, damit ich die Datei nicht öffnen und die Spalten manuell zählen muss, um zu sehen, welche Spalte welche ist, und ich muss das Skript nicht aktualisieren, wenn sich die Spaltennummer oder -reihenfolge ändert. Kann ich das mit awk (oder einem anderen Shell-Tool) tun?
Antwort1
awk '
NR==1 {
for (i=1; i<=NF; i++) {
f[$i] = i
}
}
{ print $(f["foo"]), $(f["baz"]) }
' file
foo baz
1 alpha
2 beta
3 gamma
Das ist eine äußerst nützliche Redewendung. Ich habe viele Daten in Tabellenkalkulationen und verschiedene Tabellenkalkulationen haben möglicherweise eine gemeinsame Teilmenge von Spalten, an denen ich interessiert bin, aber nicht unbedingt in derselben Reihenfolge in allen Tabellenkalkulationen oder mit derselben Anzahl anderer Spalten davor/dazwischen. Daher ist es absolut unschätzbar, sie als CSV oder Ähnliches exportieren und dann einfach ein awk-Skript mit den Spaltennamen anstelle der Spaltennummern ausführen zu können.
Antwort2
Sie fragen nach awk
, aber Sie könnten hierfür auch ein spezialisierteres Tool verwenden: csvtool
.
csvtool -t ' ' -u ' ' namedcol foo,baz file
oder
csvtool -t ' ' -u ' ' col 1,3 file
Antwort3
Angenommen, die Datei ist eine TSV-Datei ("tab separate values"), dann verwenden Siecsvkit
:
$ csvcut -t -c foo,baz file.tsv
foo,baz
1,alpha
2,beta
3,gamma
Die Ausgabe erfolgt im korrekt formatierten CSV-Format, kann aber problemlos wieder in TSV geändert werden:
$ csvcut -t -c foo,baz file.tsv | csvformat -T
foo baz
1 alpha
2 beta
3 gamma
Die -c
Option csvcut
kann auch Zahlen und Bereiche annehmen und kann auch verwendet werden, umneu anordnendie Spalten der Eingabedaten (eine Funktion, die ich im Standardprogramm oft vermisse cut
).