Hoe de uitvoer correct formatteren met de opdracht Awk printf?

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:

  1. houd dezelfde volgorde van velden aan (links -> rechts)
  2. gebruik een komma “,” FS
  3. 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:

  1. is niet in orde (links -> rechts)

  2. 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

  • Ter info: voor het scheiden van kommas zonder elke komma aan te halen, zou je 'BEGIN {OFS=","}' of gewoon

—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 '

Geef een reactie

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