AWK – print reeks kolommen

als ik een csv-bestand heb in de volgende indeling:

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

en ik wil dat awk alleen kolommen 2 t / m 7 afdrukt die ik zou gebruiken:

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

en get:

column2,column3,column4,column5,column6,column7 

is er een manier om de kolommen 2-7 samen te voegen om het commando te vereenvoudigen. Aangezien ik denk aan een bestand met nogal wat meer kolommen, zou mijn awk commando vreselijk lang worden.

Opmerkingen

  • wil je altijd een opeenvolgende set kolommen (bijv. 2-7, of 5-15 of wat dan ook)? Zo ja, dan kun je een lus gebruiken om de kolommen af te drukken. Zo niet, dan is er ' s je hoeft niet te vermijden om de individuele kolommen op te sommen die je wilt (hoewel je waar nodig een aantal loops kunt mixen). Ook hoeveel kolommen?
  • Ten slotte wil je misschien om een taal als perl of python te overwegen met een goede CSV-parser … vooral als je de kolomnamen in de eerste regel hebt (verschillende CSV-parseringsmodules van perl ' deze om een hash te construeren met de kolomnamen als sleutels. i ' m vrij zeker python ' s CSV-parsers kunnen hetzelfde doen). perl heeft ook een uitstekende array & hash-splitsingsoperatoren.
  • @cas ja, de kolommen zouden alwa ys opeenvolgend.
  • Beantwoordt dit uw vraag? Bereik van kolommen afdrukken door kommas gescheiden, en de rest zonder scheiding door kommas

Antwoord

$ 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 = beginveldnummer, e = eindveldnummer. Als u CSVs moet afhandelen met velden tussen aanhalingstekens, ingesloten kommas, nieuwe regels, enz., Raadpleeg dan https://stackoverflow.com/q/45420535/1745001 .

Answer

De utility cut heeft een compacte notatie:

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

produceren:

column2, column3, column4, column5, column6, column7

De opmerking van @PlasmaBinturong beantwoorden: mijn bedoeling was het probleem van een korte aanroepreeks aan te pakken: " … mijn awk-commando zou vreselijk lang worden … ". Men kan echter ook codes vinden die de velden naar wens rangschikken. Hoe graag ik ook awk, perl, python vind, ik heb het vaak nuttig gevonden om een specifiek hulpprogramma te bouwen om de mogelijkheden van standard * nix uit te breiden. Dus hier is een fragment uit een testscript, s2, met hulpprogrammas die opnieuw worden gesneden en gerangschikt, beide staan herschikking en duplicatie toe, waarbij schikken ook afnemende veldbereiken toelaat:

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 

resultaten produceren van deze versies:

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 

De my-recut is een kleine wijziging van de textutils-code recut, en arrangeren is onze versie van een extended cut . Meer informatie:

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 wensen … cheers, drl

Reacties

  • In tegenstelling tot Awk, voert het de kolommen uit in de volgorde van het invoerbestand, niet in de volgorde van het commando.
  • @PlasmaBinturong – zie bewerkte antwoord … proost

Antwoord

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 

Resultaten:

column2,column3,column4,column5,column6,column7 

Antwoord

Getest met onderstaande opdracht en het werkte prima

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

output

column2,column3,column4,column5,column6,column7 

Reacties

  • bedankt voor het antwoord, werkt prima zonder de " o " voor de eerste sed pipe 🙂 kon men de twee sed opdrachten samenvoegen tot één: sed "s/^,//g; s/,$//g"
  • Waarom test u het resultaat van het uitvoeren van

om te beslissen of de regel al dan niet moet worden afgedrukt? Er zijn ook andere problemen (bijv. Je hebt GEEN pijpen nodig om commandos te geven als je ' awk gebruikt!) Maar dat OFS-testgedeelte heeft absoluut geen zin …

  • @EdMorton Ik ' hoop nog steeds op een enige awk oplossing …
  • @nath waarom ? Wat is er ' mis met de cut oplossing die @drl heeft gepost ?
  • @EdMorton nee je hebt gelijk, het werkt prima. Ik dacht dat het niet te ingewikkeld kon zijn met awk en was eerder nieuwsgierig naar de kwestie die van belang was dan om een technische reden 🙂
  • Geef een reactie

    Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *