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:
- zachovat stejné pořadí polí (vlevo -> vpravo)
- mít čárku „,“ FS
- 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:
-
není v pořádku (vlevo -> vpravo)
-
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
—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 '
'BEGIN {OFS=","}'
nebo jen