質問

gawk で巨大なファイルを処理する必要があります。私の主な問題は、千の区切り文字を使用していくつかのフロートを印刷する必要があることです。例えば。: 10000 次のように表示されるはずです 10.000 そして 10000,01 として 10.000,01 出力で。

私 (そして Google) はこの関数を思いつきましたが、これは浮動小数点では失敗します。

function commas(n) {
  gsub(/,/,"",n)
  point = index(n,".") - 1
  if (point < 0) point = length(n)
    while (point > 3) {
      point -= 3
      n = substr(n,1,point)"."substr(n,point + 1)
    }
  sub(/-\./,"-",n)
  return d n
}

しかし、floatでは失敗します。

今、入力を整数と < 1 の部分に分割し、整数をフォーマットした後にそれらを再度結合することを考えていますが、それを行うより良い方法はありませんか?

免責事項:

  • 私はプログラマーではありません
  • いくつかのSHELL環境を通じてそれを知っています。変数には千の位の区切り文字を設定できますが、言語やロケールの設定が異なる異なる環境で動作する必要があります。
  • 英語は私の第二言語です、間違って使っていたらごめんなさい
役に立ちましたか?

解決

ヨーロッパ型の数値 (100 万と 4 分の 1.000.000,25) を渡しているため、float では失敗します。指定した関数は、カンマとピリオドを変更するだけで機能するはずです。まず現在のバージョンを 1000000.25 でテストして、ヨーロッパ以外の番号でも機能するかどうかを確認します。

次の awk スクリプトは次のように呼び出すことができます。 "echo 1 | awk -f xx.gawk" そして、「通常」バージョンとヨーロッパバージョンの両方が実際に動作している様子が表示されます。出力は次のとおりです。

123,456,789.1234
123.456.789,1234

明らかに、関心があるのは関数だけです。実際のコードでは、固定文字列ではなく、入力ストリームを使用して値を関数に渡します。

function commas(n) {
    gsub(/,/,"",n)
    point = index(n,".") - 1
    if (point < 0) point = length(n)
    while (point > 3) {
        point -= 3
        n = substr(n,1,point)","substr(n,point + 1)
    }
    return n
}
function commaseuro(n) {
    gsub(/\./,"",n)
    point = index(n,",") - 1
    if (point < 0) point = length(n)
    while (point > 3) {
        point -= 3
        n = substr(n,1,point)"."substr(n,point + 1)
    }
    return n
}
{ print commas("1234,56789.1234") "\n" commaseuro("12.3456789,1234") }

これらの関数は、カンマとピリオドの処理を除いて同一です。以下の説明では、これらを区切り文字と小数点と呼びます。

  • gsub は既存の区切り文字をすべて元に戻すので削除します。
  • point は、小数点が開始点であるため、小数点がどこにあるかを見つけます。
  • 小数がない場合、if ステートメントは最後から始まります。
  • 3 文字以上残っている間ループします。
  • ループ内にセパレーターを挿入する位置を調整して挿入します。
  • ループが終了したら、調整された値を返します。

他のヒント

パックスの答えに一緒に行くために、 >

/ "変換" のセクションを読みますA>これは、数値型の文字列表現上のLOCALE環境変数の効果を明確に語っています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top