Hogyan formázzuk megfelelően a kimenetet az Awk printf paranccsal?

A következő fájlom van:

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| 

Megpróbálom formázni ezt a fájlt az awk printf használatával a következő kívánt formátumot kapja:

  1. a mezők sorrendjét megtartja (bal -> jobb)
  2. vesszővel rendelkezik “,” FS
  3. csak a l ast három mezőben ($ 5, $ 6, $ 7) , amelyek mindegyikének száma négy számjegyű, ha kevesebbnek van nullája, és csak 2 számjegy van a pont után, például 0123.12 vagy 1234.10.

A következő awk parancsot írtam

awk -F"|" "{print $1","$2","$3","$4}{format = "%04.2f,%04.2f,%04.2f,"}{printf format, $5,$6,$7}" filename 

azonban az alábbi kimenetnek a következő problémái vannak:

  1. nincs rendben (bal -> jobb)

  2. nincs az első nullája

    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 

Tudna valaki tudatni velem, hogy mi a hibám és hogyan lehet kijavítani?

Megjegyzések

  • FYI, vessző elválasztáshoz az egyes vesszők idézése nélkül használhatja a 'BEGIN {OFS=","}' vagy csak

– de ez nem ' nem válaszol tágabb kérdésére.

Válasz

A mezők megfelelő sorrendben vannak, de az első nyomtatott utasítás új sort (Output Record Separator) ad hozzá, így az adatai ott vannak, de váratlanul becsomagolódnak.

A második kérdés az, hogy azt mondod a printf-nek, hogy 4 szélességet használjon; amely magában foglalja a tizedesjegyet és az utána lévő két számjegyet, csak az egyik marad a vezető számjegy számára, és egyetlen sem marad a kitöltéshez. Próbáljon szélességként 5-öt használni, hogy az adatai négy teljes számig legyenek kitöltve. Ha négy számjegyet szeretne a tizedespont elé , akkor állítsa a szélességet 7-re. want:

awk -F"|" "{ format = "%05.2f,%05.2f,%05.2f"; print $1","$2","$3","$4"," sprintf(format, $5,$6,$7)}" filename 

Több { } blokkot egyesítettem egybe, és a nyomtatott utasításokat is egybe. / p>

Ha a semmiből írnám az awk utasítást, akkor valami ilyesmit tennék:

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 

Kifejezetten beállítja a bemeneti mező elválasztót , az Output Field Separator kifejezetten átalakítja az egyes mezőket önmagában, majd kinyomtatja a kívánt mezőket, az OFS elválasztva őket.

Megjegyzések

  • Wow !!! Ez nagyszerű, és sokat tanulok. Nagyon értékeljük az időt és az informatív leírást 🙂 Legjobb!

Válasz

Ennek egyik módja:

awk -F \| -v OFS=, "{ NF--; for(i = NF-2; i <= NF; i++) $i = sprintf("%07.2f", $i) } 1" filename 

Megjegyzések

  • @ Sato Katsura, Tnx nagyon sok, tökéletesen működik. Kérem, kérem, magyarázza el a szkripteket, hogy megértsék! Új vagyok Awk-ban. Csak a szkript ezen részéhez kell magyarázat: {NF–; for (i = NF-2; i < = NF; i ++) $ i = sprintf ("% 07.2f ", $ i)} 1 '

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük