Ik heb het volgende bestand:
echo filename dfT08r352|30.5|2010/06/01|2016/08/29|2281|6.24503764544832|74.9404517453799| zm00dr121|37|2008/03/05|2011/09/12|1285.95833333333|3.52076203513575|42.249144421629| ccvd00121|41.6|2008/03/05|2012/03/05|1461|4|48| sddf00121|39.6|2008/03/05|2012/09/10|1649.95833333333|4.51733972165184|54.208076659822| fttt00121|41|2008/03/05|2013/09/16|2020.95833333333|5.53308236367785|66.3969883641342| ghhyy0121|42.2|2008/03/05|2014/03/18|2203.95833333333|6.03410905772302|72.4093086926762|
Ik probeer dit bestand te formatteren door awk printf te gebruiken om het volgende gewenste formaat te hebben:
- houd dezelfde volgorde van velden aan (links -> rechts)
- gebruik een komma “,” FS
- alleen voor de l ast drie velden ($ 5, $ 6, $ 7) met alle getallen uit 4 cijfers, als less een voorloopnul hebben en slechts 2 cijfers na het punt, zoals 0123.12 of 1234.10
Ik schreef het volgende awk-commando
awk -F"|" "{print $1","$2","$3","$4}{format = "%04.2f,%04.2f,%04.2f,"}{printf format, $5,$6,$7}" filename
de onderstaande uitvoer heeft echter de volgende problemen:
-
is niet in orde (links -> rechts)
-
heb niet de voorloopnul
dfT08r352,30.5,2010/06/01,2016/08/29 2281.00,6.25,74.94,zm00dr121,37,2008/03/05,2011/09/12 1285.96,3.52,42.25,ccvd00121,41.6,2008/03/05,2012/03/05 1461.00,4.00,48.00,sddf00121,39.6,2008/03/05,2012/09/10 1649.96,4.52,54.21,fttt00121,41,2008/03/05,2013/09/16 2020.96,5.53,66.40,ghhyy0121,42.2,2008/03/05,2014/03/18
Kan iemand me alsjeblieft laten weten wat mijn fout is en hoe ik deze kan herstellen?
Reacties
—maar dat geeft geen ' antwoord op uw bredere vraag.
Antwoord
Je hebt de velden in de juiste volgorde, maar je eerste print statement voegt een nieuwe regel toe (Output Record Separator), dus je gegevens zijn daar, maar gewoon onverwachts verpakt.
Het tweede probleem is dat je printf vertelt om een breedte van 4 te gebruiken; dat omvat het decimaalteken en de twee cijfers erna, waardoor er slechts één overblijft voor het eerste cijfer en geen voor eventuele opvulling. Probeer 5 als breedte te gebruiken, zodat uw gegevens worden opgevuld tot vier totale getallen. Als je 4 cijfers voor de komma wilt, verander dan de breedte in 7.
Dit is de kortste wijziging die ik heb gemaakt van je programma naar iets dat uitvoert wat ik denk dat je want:
awk -F"|" "{ format = "%05.2f,%05.2f,%05.2f"; print $1","$2","$3","$4"," sprintf(format, $5,$6,$7)}" filename
Ik combineerde meerdere { }
blokken tot één, en combineerde ook de printopdrachten tot één.
Als ik je awk statement helemaal opnieuw zou schrijven, zou ik zoiets als dit kunnen doen:
awk -v FS=\| -v OFS=, "{ $5=sprintf("%05.2f", $5); $6=sprintf("%05.2f", $6); $7=sprintf("%05.2f", $7); print $1,$2,$3,$4,$5,$6,$7}" filename
Het stelt expliciet de invoerveldscheidingsteken in , de Output Field Separator, converteert expliciet elk van de velden afzonderlijk en drukt vervolgens de gewenste velden af, waarbij de OFS ze scheidt.
Opmerkingen
- Wauw !!! Dit is geweldig en ik leer veel. Waardeer je tijd en informatieve beschrijving echt 🙂 Beste!
Antwoord
Een manier om het te doen:
awk -F \| -v OFS=, "{ NF--; for(i = NF-2; i <= NF; i++) $i = sprintf("%07.2f", $i) } 1" filename
Reacties
- @ Sato Katsura, Tnx werkt grotendeels perfect. Mag ik u vragen uw scripts uit te leggen om het te begrijpen! Ik ben nieuw in Awk. Je hebt alleen de uitleg nodig voor dit deel van je script: {NF–; voor (i = NF-2; i < = NF; i ++) $ i = sprintf ("% 07.2f ", $ i)} 1 '
'BEGIN {OFS=","}'
of gewoon