AWK – imprime intervalo de colunas

se eu tiver um arquivo csv no seguinte formato:

column1,column2,column3,column4,column5,column6,column7,column8 

e eu quero que awk imprima apenas as colunas 2 a 7 que eu usaria:

awk -F"," "{print $2 "," $3 "," $4 "," $5 "," $6 "," $7}" file.csv 

e get:

column2,column3,column4,column5,column6,column7 

existe uma maneira de concatenar as colunas 2 a 7 para simplificar o comando. Como estou pensando em um arquivo com um pouco mais de colunas, meu comando awk ficaria terrivelmente longo.

Comentários

  • você sempre vai querer um conjunto consecutivo de colunas (por exemplo, 2-7, ou 5-15 ou qualquer outro)? Se sim, você pode usar um loop para imprimir as colunas. Se não, existe ' s não evite listar as colunas individuais que você deseja (embora você possa misturar alguns loops quando necessário). Além disso, quantas colunas?
  • Finalmente, você pode querer considerar uma linguagem como perl ou python com um bom analisador CSV … especialmente se você tiver os nomes das colunas na primeira linha (vários módulos de análise CSV perl ' s podem usar estes para construir um hash com os nomes das colunas como chaves. i ' m bastante certeza que o python ' s analisadores CSV podem fazer o mesmo). perl também tem excelente array & operadores de processamento de hash.
  • @cas sim, as colunas estariam sempre sim consecutivos.
  • Isso responde à sua pergunta? Imprimir intervalo de colunas separadas por vírgula e o resto sem separação por vírgula

Resposta

$ awk -v b=2 -v e=7 "BEGIN{FS=OFS=","} {for (i=b;i<=e;i++) printf "%s%s", $i, (i<e ? OFS : ORS)}" file column2,column3,column4,column5,column6,column7 

b = número do campo inicial, e = número do campo final. Se você precisar lidar com CSVs com campos entre aspas, vírgulas incorporadas, novas linhas, etc., consulte https://stackoverflow.com/q/45420535/1745001 .

Resposta

O corte do utilitário tem uma notação compacta:

cut -d, -f2-7 <input-file> 

produzindo:

coluna2, coluna3, coluna4, coluna5, coluna6, coluna7

Respondendo ao comentário de @PlasmaBinturong: minha intenção era resolver o problema de uma sequência de chamada curta: " … meu comando awk ficaria terrivelmente longo … ". No entanto, também é possível encontrar códigos que organizam os campos conforme desejado. Por mais que eu goste de awk, perl, python, sempre achei útil construir um utilitário específico para estender os recursos do * nix padrão. Portanto, aqui está um trecho de um script de teste, s2, mostrando utilitários recortados e arranjados, ambos permitem reorganização e duplicação, com arranjo permitindo também intervalos de campo decrescentes:

FILE=${1-data1} # Utility functions: print-as-echo, print-line-with-visual-space. pe() { for _i;do printf "%s" "$_i";done; printf "\n"; } pl() { pe;pe "-----" ;pe "$*"; } pl " Input data file $FILE:" head $FILE pl " Results, cut:" cut -d, -f2-7 $FILE pl " Results, recut (modified as my-recut):" my-recut -d "," 7,6,2-5 < $FILE pl " Results, arrange:" arrange -s "," -f 5,3-1,7,5,3-4,5 $FILE 

produzindo resultados a partir destas versões:

OS, ker|rel, machine: Linux, 3.16.0-10-amd64, x86_64 Distribution : Debian 8.11 (jessie) bash GNU bash 4.3.30 cut (GNU coreutils) 8.23 recut - ( local: RepRev 1.1, ~/bin/recut, 2010-06-10 ) arrange (local) 1.15 ----- Input data file data1: column1,column2,column3,column4,column5,column6,column7,column8 ----- Results, cut: column2,column3,column4,column5,column6,column7 ----- Results, recut (modified as my-recut): column7,column6,column2,column3,column4,column5 ----- Results, arrange: column5,column3,column2,column1,column7,column5,column3,column4,column5 

O my-recut é uma ligeira modificação do código textutils recut, e organizar é a nossa versão de um corte estendido . Mais informações:

recut Process fields like cut, allow repetitions and re-ordering. (what) Path : ~/bin/recut Version : - ( local: RepRev 1.1, ~/bin/recut, 2010-06-10 ) Length : 56 lines Type : Perl script, ASCII text executable Shebang : #!/usr/bin/perl Home : http://www1.cuni.cz/~obo/textutils/ (doc) Modules : (for perl codes) Getopt::Long 2.42 arrange Arrange fields, like cut, but in user-specified order. (what) Path : ~/bin/arrange Version : 1.15 Length : 355 lines Type : Perl script, ASCII text executable Shebang : #!/usr/bin/perl Modules : (for perl codes) warnings 1.23 strict 1.08 Carp 1.3301 Getopt::Euclid 0.4.5 

Cumprimentos … saúde, drl

Comentários

  • Em contraste com o Awk, ele produz as colunas na ordem do arquivo de entrada, não na ordem do comando.
  • @PlasmaBinturong – veja a resposta editada … elogios

Resposta

sed -e " s/,/\n/7 ;# tag the end of col7 s/^/,/ ;# add a comma s/,/\n/2 ;# tag beginning of col2 s/.*\n\(.*\)\n.*/\1/ ;# perform surgery " file.csv 

Resultados:

column2,column3,column4,column5,column6,column7 

Resposta

Testado com o comando abaixo e funcionou bem

awk -F "," "OFS=","{$1="";$NF="";print $0}" o| sed "s/^,//g"|sed "s/,$//g" 

saída

column2,column3,column4,column5,column6,column7 

Comentários

  • obrigado pela resposta, funciona bem sem o " o " antes do primeiro sed pipe :-), era possível concatenar os dois sed comandos em um: sed "s/^,//g; s/,$//g"
  • Por que você está testando o resultado da execução de

para decidir se deseja ou não imprimir a linha? Existem outros problemas também (por exemplo, você NÃO precisa de pipes para comandos sed quando ' está usando o awk!), Mas essa parte do teste OFS não faz absolutamente nenhum sentido …

  • @EdMorton I ' ainda espero por uma única awk solução …
  • @nath por quê ? O que ' há de errado com a cut solução que @drl postou ?
  • @EdMorton não, você está certo, funciona bem. Achei que não poderia ser muito complicado com awk e estava curioso mais pelo assunto do que por uma razão técnica 🙂
  • Deixe uma resposta

    O seu endereço de email não será publicado. Campos obrigatórios marcados com *