次のファイルがあります。
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|
awk printfを使用して、このファイルを次のような目的の形式にフォーマットしようとしています。
- 同じフィールド順序を維持する(左 - >右)
- カンマ"," FSがあります
- 私だけ3つのフィールド($5、$6、$7)すべての数字は4桁です。 4桁未満の場合は、前に0が表示され、0123.12または1234.10などの点の後に2桁のみが表示されます。
私は次のawkコマンドを書いた
awk -F"|" '{print $1","$2","$3","$4}{format = "%04.2f,%04.2f,%04.2f,"}{printf format, $5,$6,$7}' filename
しかし、次の出力には次の問題があります。
順序ではない(左 - >右)
前にゼロがない
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
誰かが私のエラーが何であるか、解決策を教えてもらえますか?
答え1
フィールドの順序は正しいですが、最初の print ステートメントに改行文字 (出力レコード区切り文字) が追加され、データがそこにありますが予期せずラップされています。
2番目の問題は、printfに幅4を使用するように指示することです。小数点とその後に2桁を含め、パディングなしで1桁だけ残しておくのです。データを合計4つの数字で埋めるために、幅を5にしてみてください。 4桁が必要な場合今後小数点を入力し、幅を7に変更します。
以下は、あなたが望むものを出力するためにあなたのプログラムに最小限の変更を適用したものです。
awk -F"|" '{
format = "%05.2f,%05.2f,%05.2f";
print $1","$2","$3","$4"," sprintf(format, $5,$6,$7)}' filename
{ }
複数のブロックを1つにまとめ、ステートメントを1つに印刷しました。
最初からawkステートメントを作成する場合は、次のようにできます。
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
入力フィールド区切り記号である出力フィールド区切り文字を明示的に設定し、各フィールド自体を明示的に変換し、必要なフィールドを印刷してOFSを使用して区切ります。
答え2
1つの方法は次のとおりです。
awk -F \| -v OFS=, '{ NF--; for(i = NF-2; i <= NF; i++) $i = sprintf("%07.2f", $i) } 1' filename