hvis jeg har en csv-fil i følgende format:
column1,column2,column3,column4,column5,column6,column7,column8
og jeg vil have, at awk
kun udskriver kolonner 2 til 7, som jeg bruger:
awk -F"," "{print $2 "," $3 "," $4 "," $5 "," $6 "," $7}" file.csv
og get:
column2,column3,column4,column5,column6,column7
er der en måde at sammenkæde kolonnerne 2-7 for at forenkle kommandoen. Da jeg tænker på en fil med en hel del flere kolonner, ville min awk
kommando blive frygtelig lang.
Kommentarer
- vil du altid have et række kolonner i træk (f.eks. 2-7 eller 5-15 eller hvad som helst)? Hvis ja, kan du bruge en løkke til at udskrive kolonnerne. Hvis ikke, er der ' er ikke undgå at angive de enkelte kolonner, du ønsker (selvom du kan blande nogle sløjfer, hvor det er nødvendigt). Hvor mange kolonner?
- Endelig vil du muligvis at overveje et sprog som perl eller python med en god CSV-parser …. især hvis du har kolonnenavnene i første linje (flere af perl ' s CSV-parsemoduler kan bruge disse for at konstruere en hash med kolonnenavnene som nøgler. i ' m ret sikker python ' s CSV-parsere kan gøre lignende). perl har også fremragende array & hash splejsning operatører.
- @cas ja kolonnerne ville være alwa er i træk.
- Besvarer dette dit spørgsmål? Udskriv række af kolonner kommasepareret og resten uden kommaadskillelse
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 = slutfeltnummer. Hvis du har brug for at håndtere CSVer med citerede felter, indlejrede kommaer, nye linjer osv., Se https://stackoverflow.com/q/45420535/1745001 .
Svar
Hjælpeprogrammet har en kompakt notation:
cut -d, -f2-7 <input-file>
producerer:
kolonne2, kolonne3, kolonne4, kolonne5, kolonne6, kolonne7
Besvarelse af kommentaren fra @PlasmaBinturong: min hensigt var at løse problemet med en kort opkaldssekvens: " … min awk-kommando ville blive forfærdeligt lang … ". Man kan dog også finde koder, der arrangerer felterne, som man måtte ønske. Så meget som jeg kan lide awk, perl, python, har jeg ofte fundet det nyttigt at opbygge et specifikt værktøj for at udvide funktionerne i standard * nix. Så her er et uddrag fra et test script, s2, der viser hjælpeprogrammer genoptage og arrangere, begge tillader omarrangering og duplikering, med arrangerer også mulighed for faldende 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
producerer resultater fra disse 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 er en lille ændring af tekstudnyttelseskodens recut, og arrangere er vores version af et udvidet snit . Flere oplysninger:
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
Bedste ønsker … skål, drl
Kommentarer
- I modsætning til Awk udsender den kolonnerne i rækkefølgen af inputfilen, ikke i rækkefølgen af kommandoen.
- @PlasmaBinturong – se redigeret 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 nedenstående kommando, og det fungerede fint
awk -F "," "OFS=","{$1="";$NF="";print $0}" o| sed "s/^,//g"|sed "s/,$//g"
output
column2,column3,column4,column5,column6,column7
Kommentarer
- tak for svaret, fungerer fint uden " o " før første
sed
pipe 🙂 kunne man sammenkæde de tosed
kommandoer til en:sed "s/^,//g; s/,$//g"
- Hvorfor tester du resultatet af udførelsen af
for at beslutte, om linjen skal udskrives eller ej? Der er også andre problemer (f.eks. Har du IKKE brug for rør for at sed-kommandoer, når du ' bruger awk!) Men den OFS-testdel giver absolut ingen mening …
awk
opløsning … cut
-løsningen, som @drl indsendte ? awk
og var nysgerrig snarere af interesse af interesse af en teknisk årsag 🙂