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 …
awk
lösning … cut
-lösningen som @drl publicerade ? awk
och var nyfiken snarare av intresse än av teknisk anledning 🙂