Imprimir colunas no awk pelo nome do cabeçalho


11

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 determinadas 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, portanto, não preciso 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)?

Respostas:


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

Esse é um idioma imensamente útil. Eu tenho muitos dados em planilhas e diferentes planilhas 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 eles 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.


Isso é muito obrigado e funciona para meus propósitos. Você é capaz de esclarecer como isso funciona para um iniciante desajeitado? O que a sintaxe f [$ i] está fazendo nisso e como o awk calcula quais colunas correspondem às strings?
AlexLipp

Seja bem-vindo. Essa é a sintaxe absolutamente básica do awk, basta procurar campos e matrizes na página de manual do awk (ou no google). Adicionar print ie print $ie print f [$ i] `instruções no loop, etc. para rastrear o que está acontecendo se isso ajuda.
Ed Morton

0

Você pede awk, mas você 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

0

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

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

A saída será CSV formatada corretamente, mas poderá ser facilmente alterada novamente 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 para reorganizar as colunas dos dados de entrada (um recurso que muitas vezes sinto falta no cututilitário padrão ).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.