AWK – skriv ut kolumner

om jag har en csv-fil i följande format:

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

och jag vill att awk bara ska skriva ut kolumner 2 till 7 som jag skulle använda:

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

och få:

column2,column3,column4,column5,column6,column7 

finns det ett sätt att sammanfoga kolumnerna 2-7 för att förenkla kommandot. När jag tänker på en fil med en hel del fler kolumner skulle mitt awk -kommando bli väldigt långt.

Kommentarer

  • vill du alltid ha en rad kolumner i rad (t.ex. 2-7 eller 5-15 eller vad som helst)? Om så är fallet kan du använda en slinga för att skriva ut kolumnerna. Om inte, finns det ’ s undviker att lista de enskilda kolumnerna du vill ha (även om du kan blanda i några slingor där det behövs). Hur många kolumner?
  • Slutligen kanske du vill att överväga ett språk som perl eller python med en bra CSV-parser …. speciellt om du har kolumnnamnen i första raden (flera av perl ’ s CSV-parsningsmoduler kan använda dessa för att konstruera en hash med kolumnnamnen som nycklar. i ’ m ganska säker python ’ s CSV-parsers kan göra liknande). perl har också utmärkt array & hash-splitsningsoperatorer.
  • @cas ja kolumnerna skulle vara alwa ys i följd.
  • Svarar det på din fråga? Skriv ut kolumner med kommaseparerade och resten utan kommaseparation

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 = startfältnummer, e = slutfältnummer. Om du behöver hantera CSV-filer med citerade fält, inbäddade kommatecken, nya rader etc., se https://stackoverflow.com/q/45420535/1745001 .

Svar

Verktygssnittet har en kompakt notation:

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

producerar:

kolumn2, kolumn3, kolumn4, kolumn5, kolumn6, kolumn7

Svar på kommentaren av @PlasmaBinturong: min avsikt var att ta itu med frågan om en kort samtalsekvens: ” … mitt awk-kommando skulle bli väldigt långt … = ”52775922c7”>

. Man kan dock också hitta koder som ordnar fälten som man kan önska. Så mycket som jag gillar awk, perl, python har jag ofta funnit det användbart att bygga ett specifikt verktyg för att utöka funktionerna för standard * nix. Så här är ett utdrag från ett testskript, s2, som visar verktygen omskärning och ordning, båda tillåter omarrangemang och duplicering, med ordning som också möjliggör minskande fältintervall:

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 

producerar resultat från dessa versioner:

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 är en liten modifiering av textutils kod recut, och arrangera är vår version av en utökad klippning . Mer information:

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 

Bästa hälsningar … skål, drl

Kommentarer

  • Till skillnad från Awk matar den ut kolumnerna i inmatningsfilens ordning, inte i ordningens ordning.
  • @PlasmaBinturong – se redigerat 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 

Resultat:

column2,column3,column4,column5,column6,column7 

Svar

Testat med kommandot nedan och det fungerade bra

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

output

column2,column3,column4,column5,column6,column7 

Kommentarer

  • tack för svaret, fungerar bra utan ” o ” före första sed pipe 🙂 man kunde sammanfoga de två sed kommandona till en: sed "s/^,//g; s/,$//g"
  • Varför testar du resultatet av att köra

för att bestämma om raden ska skrivas ut eller inte? Det finns också andra problem (t.ex. du behöver INTE rör för att sed-kommandon när du ’ använder awk!) Men den OFS-testdelen ger absolut ingen mening …

  • @EdMorton I ’ jag hoppas fortfarande på en enda awk lösning …
  • @nath varför ? Vad ’ är fel med cut -lösningen som @drl publicerade ?
  • @EdMorton nej du har rätt, det fungerar bra. Jag trodde att det inte kunde vara för komplicerat med awk och var nyfiken snarare av intresse än av teknisk anledning 🙂
  • Lämna ett svar

    Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *