AWK – tipăriți gama de coloane

dacă am un fișier csv în formatul următor:

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

și vreau ca awk să imprime doar coloanele 2 până la 7, aș folosi:

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

și get:

column2,column3,column4,column5,column6,column7 

există o modalitate de a concatena coloanele 2-7 pentru a simplifica comanda. Întrucât mă gândesc la un fișier cu mai multe coloane, comanda mea awk ar deveni îngrozitor de lungă.

Comentarii

  • doriți întotdeauna un set consecutiv de coloane (de exemplu, 2-7 sau 5-15 sau orice altceva)? dacă da, puteți utiliza o buclă pentru a imprima coloanele. Dacă nu, acolo ' nu evită listarea coloanelor individuale pe care le doriți (deși puteți amesteca în unele bucle acolo unde este necesar). De asemenea, câte coloane?
  • În cele din urmă, ați putea dori să luați în considerare o limbă precum perl sau python cu un bun analizor CSV …. mai ales dacă aveți numele coloanelor în prima linie (mai multe dintre modulele de analiză CSV perl ' pot utiliza acestea pentru a construi un hash cu numele coloanelor ca chei. i ' m destul de sigur că Python ' s analizatorii CSV pot face similar). perl are, de asemenea, o gamă excelentă de operatori de divizare hash &.
  • @cas da, coloanele ar fi alwa Este consecutiv.
  • Vă răspunde la întrebare? Imprimați gama de coloane separate prin virgulă, iar restul fără separarea prin virgulă

Răspuns

$ 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 = numărul câmpului de început, e = numărul câmpului de sfârșit. Dacă trebuie să gestionați CSV-uri cu câmpuri citate, virgule încorporate, linii noi etc., consultați https://stackoverflow.com/q/45420535/1745001 .

Răspuns

Utilitarul tăiat are o notație compactă:

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

producere:

column2, column3, column4, column5, column6, column7

Răspuns la comentariul de @PlasmaBinturong: intenția mea era să abordez problema unei secvențe scurte de apelare: " … comanda mea awk ar fi oribil de lungă … ". Cu toate acestea, se pot găsi și coduri care aranjează câmpurile așa cum s-ar putea dori. Oricât de mult îmi plac awk, perl, python, mi s-a părut de multe ori util să construiesc un utilitar specific pentru a extinde capacitățile standard * nix. Deci, iată un extras dintr-un script de test, s2, care arată utilitățile recutate și aranjate, ambele permit rearanjarea și duplicarea, cu aranjarea care permite, de asemenea, intervalele de câmp descrescătoare:

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 

producând rezultate din aceste versiuni:

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 

My-recut este o ușoară modificare a codului textutils recut și aranjarea este versiunea noastră a unei tăieturi extinse . Mai multe informații:

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 

Cele mai bune urări … urale, drl

Comentarii

  • Spre deosebire de Awk, scoate coloanele în ordinea fișierului de intrare, nu în ordinea comenzii.
  • @PlasmaBinturong – vezi răspunsul modificat … noroc

Răspuns

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 

Rezultate:

column2,column3,column4,column5,column6,column7 

Răspuns

Testat cu comanda de mai jos și a funcționat bine

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

ieșire

column2,column3,column4,column5,column6,column7 

Comentarii

  • mulțumesc pentru răspuns, funcționează bine fără " o " înainte de prima sed conductă 🙂 s-ar putea concatena cele două comenzi sed într-o singură: sed "s/^,//g; s/,$//g"
  • De ce testați rezultatul executării

pentru a decide dacă tipăriți sau nu linia? Există și alte probleme (de exemplu, NU aveți nevoie de conducte pentru a comanda sed când ' utilizați awk!), Dar partea de test OFS nu are absolut nici un sens …

  • @EdMorton Am ' încă sper în soluționarea awk
  • @nath de ce ? Ce ' este greșit cu soluția cut pe care @drl a postat-o ?
  • @EdMorton nu, ai dreptate, funcționează bine. Am crezut că nu poate fi prea complicat cu awk și am fost curioasă mai degrabă pentru chestiunea de interes, apoi dintr-un motiv tehnic 🙂
  • Lasă un răspuns

    Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *