[コマンド] bc(数値計算ソフト)の結果出力で、小数点前の0(ゼロ)を省略させないようにする方法

別のブログ記事
[コマンド] bc(数値計算ソフト)でコマンドラインから計算式を渡して出力させる方法
でbcのコマンドラインからの使い方について紹介しました。
その続きとして、bcの計算結果出力で小数点の前の数字が0(ゼロ)の場合に0を省略させないで表示する方法について考えていきます。

[何が問題となるか?]

bcで1/3を計算させると、始めに貼ったスクリーンショットみたいに「.333333」のように出力されます。ただ「0.333333」のような表示に慣れていると0が省略されると若干違和感を覚えます。自分が結果を読むだけならほぼ慣れの問題で済むのですが、他の人に見せたり別のコマンドへ値を渡すという場面では0を省略させない方がいい場合もあります。残念ながらbcの出力のカスタマイズでそういった変更を行う項目は無いようです。そこで、別の方法と組み合わせることで0を省略させないようにしてみることにします。

[数字として別のコマンドで整形して出力する方法]

まずawkというコマンドを併用する方法がWebを検索するとよく紹介されているようでした。
$ echo "scale=5; 1/3" | bc | awk '{printf "%.5f\n", $0}'

awk自体の説明をしていくと長くなり過ぎるので、ここでは単に出力整形を行うものとして使うものとして考えておきます。上記のコマンドを説明すると、awkの出力でprintfで整形するようにして"%.5f"で小数点以下何桁まで表示するか指定します。数字はbcのscaleと同じ値にしておきます。"\n"は出力の最後に改行を付けるものです。まぁ無くても出力自体には問題は無いので、改行があった方がいい場合は付けるようにするといいでしょう。

また別解としてxargsで結果をprintfコマンドに渡して出力させる方法もあるようです。
$ echo "scale=5; 1/3" | bc | xargs printf %.5f

(xargsも説明し出すと長くなるので、説明は省略)

[数字ではなく文字列として対処する方法]

さて、これで対応出来たわけですが、細かいところを言うと完全には対応しきれないようです。例えばbcのscaleの値をかなり大きめに振ってやると(printfの桁数もそれに合わせる)、ある桁数から出力の値が一致しなくなります。おそらく受け手のコマンドの数字を扱える上限によるもの(変数の型とか)と思われます。なので正確性が求められる場面ではもう少し策を練る必要が出てきます。

改めて目標設定を確認すると「小数点前のゼロを省略させないようにする」ということでした。それを踏まえると、数字を数字のまま受けて処理するのは必ずしも必要ではありません。単に文字列として受けて文頭の「.」を「0.」に変換するだけでも解決することが出来ます。
(注意点としては「10.23」のような場合に考えなしに変換すると「100.23」となってしまいます)
条件としては文頭に「.」がある場合に限り「0.」に変換すればいいわけで、主にそういった場面ではsedというコマンドが用いられます。
sedの使い方などを押さえる必要があるのですが、簡単には以下のようになります。
$ echo "scale=30; -1/3" | bc | sed 's/^\./0./'

なおこの方法でも完璧ではなく、「-.231564」のようにマイナスの値には対処出来ません。ただ、sedを使う方法を押さえておけばそのような場合も含めて対処することは出来るので、興味がある方は考えてみて下さい。

補足
bcはある文字数で自動で改行が挟まれますが、それについてはbcの環境変数のそれに関わるものの値を変更することで対処出来ます。
無理にbcを使おうとすると煩雑な書き方になってしまうので、どういったことをしたいのかによってbc以外のコマンドを使うことも考えた方がいいでしょう。

参考サイト

コメント