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 -c
opção csvcut
també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 cut
utilitário padrão).