AWK – skriv ut kolonneområdet

hvis jeg har en csv-fil i følgende format:

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

og jeg vil at awk bare skal skrive ut kolonnene 2 til 7 jeg vil bruke:

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

og få:

column2,column3,column4,column5,column6,column7 

er det en måte å sammenkoble kolonnene 2-7 for å forenkle kommandoen. Når jeg tenker på en fil med ganske mange flere kolonner, vil awk -kommandoen bli veldig lang.

Kommentarer

  • vil du alltid ha et påfølgende sett med kolonner (f.eks. 2-7 eller 5-15 eller hva som helst)? I så fall kan du bruke en løkke til å skrive ut kolonnene. Hvis ikke, er det ' er uten å unngå å oppgi de enkelte kolonnene du vil ha (selv om du kan blande inn noen sløyfer der det er nødvendig). Hvor mange kolonner?
  • Til slutt vil du kanskje å vurdere et språk som perl eller python med en god CSV-parser …. spesielt hvis du har kolonnenavnene i første linje (flere av perl ' s CSV-parsemoduler kan bruke disse for å konstruere en hash med kolonnenavnene som nøkler. i ' m ganske sikker på at python ' s CSV-parsere kan gjøre lignende). perl har også utmerket matriser & hash-spleisningsoperatorer.
  • @cas ja kolonnene ville være alwa er påfølgende.
  • Svarer dette på spørsmålet ditt? Skriv ut kolonneområdet kommaseparert, og resten uten komma-separasjon

Svar

$ 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 = startfeltnummer, e = sluttfeltnummer. Hvis du trenger å håndtere CSV-er med siterte felt, innebygde kommaer, nye linjer osv., Se https://stackoverflow.com/q/45420535/1745001 .

Svar

Verktøykuttet har en kompakt notasjon:

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

produserer:

kolonne2, kolonne3, kolonne4, kolonne5, kolonne6, kolonne7

Svar på kommentaren fra @PlasmaBinturong: min hensikt var å løse problemet med en kort anropssekvens: " … min awk-kommando ville bli fryktelig lang … ". Imidlertid kan man også finne koder som ordner feltene slik man måtte ønske. Så mye som jeg liker awk, perl, python, har jeg ofte funnet det nyttig å bygge et bestemt verktøy for å utvide funksjonene til standard * nix. Så her er et utdrag fra et testskript, s2, som viser verktøyene tilbakestille og ordne, begge tillater omorganisering og duplisering, med ordne som også tillater avtagende feltområder:

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 

produserer resultater fra disse versjonene:

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 er en liten modifisering av tekstutnyttelseskoden, og ordne er vår versjon av et utvidet kutt . Mer informasjon:

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 

Beste ønsker … skål, drl

Kommentarer

  • I motsetning til Awk skriver den ut kolonnene i rekkefølgen på inndatafilen, ikke i rekkefølgen på kommandoen.
  • @PlasmaBinturong – se redigert svar … skål

Svar

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 

Resultater:

column2,column3,column4,column5,column6,column7 

Svar

Testet med kommandoen nedenfor, og den fungerte bra

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

output

column2,column3,column4,column5,column6,column7 

Kommentarer

  • takk for svaret, fungerer fint uten " o " før første sed pipe 🙂 kunne man sammenkoble de to sed kommandoene til en: sed "s/^,//g; s/,$//g"
  • Hvorfor tester du resultatet av å utføre

for å bestemme om linjen skal skrives ut eller ikke? Det er andre problemer også (for eksempel trenger du IKKE rør for å sed-kommandoer når du ' bruker awk!) Men den OFS-testdelen gir ingen mening …

  • @EdMorton I ' jeg håper fremdeles på en eneste awk løsning …
  • @nath hvorfor ? Hva ' er galt med cut løsningen som @drl postet ?
  • @EdMorton nei du har rett, det fungerer bra. Jeg trodde det ikke kunne være for komplisert med awk og var nysgjerrig på det av interesse av en teknisk grunn 🙂
  • Legg igjen en kommentar

    Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *