Drucken Sie die Spalten in awk nach dem Headernamen

11

Ich habe so eine Textdatei

foo bar baz
1   a   alpha
2   b   beta
3   c   gamma

Ich kann awk verwenden, um bestimmte Spalten wie 1 und 3 mit {print $1, $3}zu drucken, aber ich möchte die zu druckenden Spalten angeben, indem ich stattdessen die Kopfzeile der Spalte wie etwa anspreche {print $foo, $baz}. Dies 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) machen?

user1350864
quelle

Antworten:

16
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 immens 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 über alle Tabellenkalkulationen hinweg oder mit der gleichen Anzahl anderer Spalten vor / zwischen ihnen, damit sie exportiert werden können Sie als CSV oder ähnliches zu verwenden und dann einfach ein awk-Skript mit den Spaltennamen anstelle der Spaltennummern auszuführen, ist absolut von unschätzbarem Wert.

Ed Morton
quelle
Das ist ein großer Dank und funktioniert für meine Zwecke. Können Sie klären, wie dies für einen awk-Anfänger funktioniert? Was macht die f [$ i] -Syntax dabei und wie ermittelt awk, welche Spalten mit den Zeichenfolgen übereinstimmen?
AlexLipp
Bitte. Das ist eine absolut grundlegende awk-Syntax. Suchen Sie einfach nach Feldern und Arrays in der awk-Manpage (oder googeln Sie sie). Fügen Sie print iund print $iund print f [$ i] `Anweisungen in die Schleife usw. ein, um zu verfolgen, was passiert, wenn dies hilft.
Ed Morton
0

Sie fragen nach awk, können aber auch ein spezielleres Tool verwenden : csvtool.

csvtool -t ' ' -u ' ' namedcol foo,baz file

oder

csvtool -t ' ' -u ' ' col 1,3 file
pLumo
quelle
0

Angenommen, die Datei ist eine TSV-Datei ("tabulatorgetrennte Werte"). Verwenden Sie dazu csvkit:

$ csvcut -t -c foo,baz file.tsv
foo,baz
1,alpha
2,beta
3,gamma

Die Ausgabe wird ordnungsgemäß in CSV formatiert, kann jedoch leicht wieder in TSV geändert werden:

$ csvcut -t -c foo,baz file.tsv | csvformat -T
foo     baz
1       alpha
2       beta
3       gamma

Die -cOption csvcutkann auch Zahlen und Bereiche annehmen und auch zum Neuanordnen der Spalten der Eingabedaten verwendet werden (eine Funktion, die ich im Standarddienstprogramm häufig vermisse cut).

Kusalananda
quelle