Jak správně formátovat výstup pomocí příkazu Awk printf?

Mám následující soubor:

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| 

Pokouším se formátovat tento soubor pomocí awk printf získáte následující požadovaný formát:

  1. zachovat stejné pořadí polí (vlevo -> vpravo)
  2. mít čárku „,“ FS
  3. pouze pro l ast tři pole ($ 5, $ 6, $ 7) se všemi čtyřmístnými čísly, pokud méně má počáteční nulu a pouze 2 číslice za bodem jako 0123.12 nebo 1234.10

Napsal jsem následující příkaz awk

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

následující výstup má však následující problémy:

  1. není v pořádku (vlevo -> vpravo)

  2. nemáte úvodní nulu

    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 

Může mi někdo prosím sdělit, jaká je moje chyba a jak ji opravit?

Komentáře

  • FYI, pro oddělení čárkami bez uvedení každé čárky můžete použít 'BEGIN {OFS=","}' nebo jen

—ale ' neodpovídá na vaši širší otázku.

Odpověď

Máte pole ve správném pořadí, ale váš první tiskový příkaz přidá nový řádek (oddělovač výstupních záznamů), takže vaše data jsou tam, ale neočekávaně zalomená.

Druhým problémem je, že říkáte printf, aby používal šířku 4; to zahrnuje desetinnou čárku a dvě číslice za ní, přičemž pouze jedna pro počáteční číslici a žádná pro jakoukoli výplň. Zkuste použít 5 jako šířku, aby byla vaše data vyplněna až čtyřmi celkovými čísly. Pokud chcete 4 číslice před desetinnou čárkou, změňte místo toho šířku na 7.

Toto je nejkratší změna, kterou jsem provedl z vašeho programu, na něco, z čeho vychází to, co si myslím, že vy chtít:

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

Zkombinoval jsem několik bloků { } do jednoho a také jsem spojil tiskové příkazy do jednoho.

Pokud bych měl napsat vaše awk prohlášení od nuly, mohl bych udělat něco takového:

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 

Explicitně nastavuje vstupní oddělovač polí , oddělovač výstupních polí, výslovně převádí každé z polí samostatně a poté vytiskne požadovaná pole, přičemž je odděluje OFS.

Komentáře

  • Páni !!! To je skvělé a hodně se učím. Opravdu oceníte svůj čas a informativní popis 🙂 Nejlepší!

Odpověď

Jeden způsob, jak to udělat:

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

Komentáře

  • @ Sato Katsura, Tnx, hodně to funguje perfektně. Mohu vás požádat, prosím, vysvětlete svým skriptům, abyste tomu porozuměli! Jsem nový ve službě Awk. Potřebujete pouze vysvětlení pro tuto část skriptu ur: {NF–; pro (i = NF-2; i < = NF; i ++) $ i = sprintf ("% 07.2f ", $ i)} 1 '

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *