Cetak kolom dalam awk dengan nama header


11

Saya memiliki file teks seperti itu

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

Saya dapat menggunakan awk untuk mencetak kolom tertentu, seperti 1 dan 3, dengan {print $1, $3}, tapi saya ingin menentukan kolom yang akan dicetak dengan menentukan header kolom sebagai gantinya, kira-kira seperti {print $foo, $baz}. Ini berguna jadi saya tidak perlu membuka file dan menghitung kolom secara manual untuk melihat kolom mana yang mana, dan saya tidak perlu memperbarui skrip jika nomor kolom atau pesanan berubah. Bisakah saya melakukan ini dengan awk (atau alat shell lain)?

Jawaban:


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

Itu adalah ungkapan yang sangat berguna. Saya memiliki banyak data dalam spreadsheet dan spreadsheet yang berbeda mungkin memiliki subset kolom yang sama dengan yang saya minati tetapi tidak harus dalam urutan yang sama di semua spreadsheet atau dengan jumlah kolom yang sama sebelum / di antara mereka sehingga dapat mengekspor mereka sebagai CSV atau serupa dan kemudian jalankan skrip awk menggunakan nama kolom, bukan nomor kolom benar-benar tak ternilai.


Ini terima kasih dan bekerja untuk tujuan saya. Apakah Anda dapat mengklarifikasi cara kerjanya untuk pemula yang awk? Apa yang dilakukan sintaks f [$ i] dalam hal ini, dan bagaimana awk menentukan kolom mana yang cocok dengan string?
AlexLipp

Sama-sama. Itu sintaks awk benar-benar dasar, hanya mencari bidang dan array di halaman manual awk (atau google it). Tambahkan print idan print $idan print [$ i] pernyataan `dalam loop, dll. Untuk melacak apa yang terjadi jika itu membantu.
Ed Morton

0

Anda meminta awk, tetapi Anda juga bisa menggunakan alat yang lebih khusus untuk ini: csvtool.

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

atau

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

0

Dengan asumsi bahwa file tersebut adalah file TSV ("tab separated values"), menggunakan csvkit:

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

Output akan CSV diformat dengan benar, tetapi dapat dengan mudah diubah kembali ke TSV:

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

The -cpilihan untuk csvcutjuga dapat mengambil nomor dan rentang, dan juga dapat digunakan untuk mengatur ulang kolom input data (fitur saya sering melewatkan dalam standar cututilitas).

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.