Imprimir colunas no awk pelo nome do cabeçalho

Imprimir colunas no awk pelo nome do cabeçalho

Eu tenho um arquivo de texto assim

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

Posso usar o awk para imprimir certas colunas, como 1 e 3, com {print $1, $3}, mas quero especificar as colunas a serem impressas especificando o cabeçalho da coluna, algo como {print $foo, $baz}. Isso é útil para que não precise abrir o arquivo e contar as colunas manualmente para ver qual coluna é qual, e não preciso atualizar o script se o número ou a ordem da coluna mudar. Posso fazer isso com o awk (ou outra ferramenta shell)?

Responder1

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

Essa é uma expressão imensamente útil. Tenho muitos dados em planilhas e planilhas diferentes podem ter um subconjunto comum de colunas nas quais estou interessado, mas não necessariamente na mesma ordem em todas as planilhas ou com o mesmo número de outras colunas antes/entre elas, para poder exportar colocá-los como CSV ou similar e simplesmente executar um script awk usando os nomes das colunas em vez dos números das colunas é absolutamente inestimável.

Responder2

Você pede awk, mas também pode usar uma ferramenta mais especializada para isso: csvtool.

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

ou

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

Responder3

Supondo que o arquivo seja um arquivo TSV ("valores separados por tabulação"), usandocsvkit:

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

A saída será CSV formatada corretamente, mas poderá facilmente ser alterada de volta para TSV:

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

A -copção csvcuttambém pode receber números e intervalos, e também pode ser usada parareorganizaras colunas dos dados de entrada (um recurso que muitas vezes sinto falta no cututilitário padrão).

informação relacionada