ヘッダー名でawkの列を印刷する


11

私はそのようなテキストファイルを持っています

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

awkを使用して、1や3などの特定の列を印刷できます{print $1, $3}が、代わりに、列のヘッダーを指定して、印刷する列を指定します{print $foo, $baz}。これは便利なので、ファイルを開いて列を数え、どの列がどれかを確認する必要はありません。また、列番号や順序が変わった場合にスクリプトを更新する必要もありません。これをawk(または別のシェルツール)で実行できますか?

回答:


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

それは非常に便利なイディオムです。スプレッドシートに多くのデータがあり、異なるスプレッドシートには関心のある列の共通サブセットがあるかもしれませんが、必ずしもすべてのスプレッドシートで同じ順序であるか、それらの前/間で同じ数の他の列があるため、エクスポートできますそれらをCSVまたは同様のものとして、列番号の代わりに列名を使用してawkスクリプトを実行することは絶対に貴重です。


これは大きな感謝であり、私の目的のために機能します。これがawk初心者のためにどのように機能するかを明確にすることができますか?これでf [$ i]構文は何をしているのですか、またawkはどの列が文字列に一致するかをどのように計算しますか?
AlexLipp

どういたしまして。これは完全に基本的なawk構文です。awkのmanページ(またはgoogleで)でフィールドと配列を検索してください。ループ内にprint iand print $iおよびprint f [$ i] `ステートメントを追加して、それが役立つ場合に何が起こっているかを追跡します。
Ed Morton

0

を要求しawkますが、これに特化したツールを使用することもできますcsvtool

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

または

csvtool -t ' ' -u ' ' col 1,3 file

0

ファイルがTSV(「タブ区切り値」)ファイルであると想定すると、次のように使用しcsvkitます。

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

出力は適切にフォーマットされたCSVになりますが、TSVに簡単に戻すことができます。

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

-cするオプションcsvcutも番号および範囲を取ることができ、また、ために使用することができます並べ替え、入力データの列(私は多くの場合、標準で欠場機能cutユーティリティ)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.