Stampa le colonne in awk per nome dell'intestazione


11

Ho un file di testo come questo

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

Posso usare awk per stampare determinate colonne, come 1 e 3, con {print $1, $3}, ma voglio specificare le colonne da stampare specificando invece l'intestazione della colonna, qualcosa del genere {print $foo, $baz}. Questo è utile, quindi non devo aprire il file e contare manualmente le colonne per vedere quale colonna è, e non devo aggiornare lo script se il numero della colonna o l'ordine cambia. Posso farlo con awk (o un altro strumento shell)?

Risposte:


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

Questo è un linguaggio immensamente utile. Ho molti dati in fogli di calcolo e fogli di calcolo diversi potrebbero avere un sottoinsieme comune di colonne a cui sono interessato, ma non necessariamente nello stesso ordine su tutti i fogli di calcolo o con lo stesso numero di altre colonne prima / tra di loro in modo da poter esportare come CSV o simili e quindi semplicemente eseguire uno script awk usando i nomi delle colonne anziché i numeri delle colonne è assolutamente prezioso.


Questo è un grande grazie e funziona per i miei scopi. Sei in grado di chiarire come funziona per un principiante awk? Cosa sta facendo la sintassi f [$ i] in questo, e come fa awk a capire quali colonne corrispondono alle stringhe?
AlexLipp,

Prego. Questa è una sintassi Awk di base, basta cercare i campi e gli array nella pagina man di Awk (o cercarla su Google). Aggiungere print ied print $ie print f [$ i] dichiarazioni `nel ciclo, ecc per tracciare quello che accade se questo aiuta.
Ed Morton,

0

Si chiede awk, ma si potrebbe anche usare uno strumento più specializzato per questo: csvtool.

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

o

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

0

Supponendo che il file sia un file TSV ("valori separati da tabulazione"), usando csvkit:

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

L'output verrà formattato correttamente in CSV, ma potrebbe essere facilmente ripristinato in TSV:

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

L' -copzione csvcutpuò anche prendere numeri e intervalli e può anche essere utilizzata per riorganizzare le colonne dei dati di input (una caratteristica che spesso mi manca cutnell'utilità standard ).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.