シェルで値を科学表記から10進数に変換する方法は? (推奨Cシェル)
また、e-12からe-9に変換してからシェルに変換したいと思います
42.53e-12から0.04253。リストのためにこれをしなければなりません。
printf
はシェルからこれを行います。
$ FOO=42.53e-12
$ BAR=$(printf "%.14f" $FOO)
$ echo $BAR
0.00000000004253
$
古代+難解なCシェルでは、これはそうなります。
$ set FOO=42.53e-12
$ set BAR=`printf "%.14f" $FOO`
$ echo $BAR
0.00000000004253
$
多くのシェル(特に古代+難解なcsh)は、浮動小数点演算を理解していません。
ほとんどのシェルには、「科学的フォーマット」を理解する組み込みのprintf
があります。
$ printf '%5.0f\n' '1e3'
1000
しかし、すべてのprintfは計算できません計算できません:
$ printf '%5.0f\n' '1e3+1e3'
printf: ‘1e3+1e3’: value not completely converted
Cshには2つのステップで回避策があります。 - 最初
数値を18桁未満の10進数に変換します(64ビット浮動小数点のうち53ビット有効の場合)。[a]:
% printf "%.18f\n" "42.53e-12"
0.000000000042530000
二番目
(要求どおりに)1e3
を掛けて、もう一度印刷します。
% printf '%.15f\n' "`printf "%.18f" "42.53e-12"`e3"
0.000000042530000
もちろん、printf
のcsh
は、独自のフロートサイズ(64ビット?)を持つ外部ユーティリティであり、OSによって異なる場合があります。
数学(シェル以外)を行うにはbc
を考えるのが自然ですが、bcには独自の制限があります(e
を指数として理解していないため、10^
に変換する必要があります)。 これを読む 。
しかし、awkはそれを行うことができます。
% echo 42.53e-12 | awk '{printf("%.15f\n", $1*1e3)}'
0.000000042530000
Awkは53ビットの有効桁数を使用するため、15桁を超える正しい数字を期待しないでください。より多くを得るには、GNU awkのバージョンで、任意精度モジュールがコンパイルされている必要があります。
% echo 42.53e-12 | awk -M -v PREC=134 '{printf("%.40g\n", $1*1e3)}'
4.253e-08
これは、40桁までの10進数で134バイナリビットです。 10進数として:
% echo 42.53e-12 | awk -M -v PREC=134 '{printf("%.40f\n", $1*1e3)}'
0.0000000425300000000000000000000000000000
あなたの質問では、あなたは述べています:
リストのためにこれをしなければなりません。
しかし、それがどのようなリストであるかについての詳細は明記しないでください。リストが(シェル変数としてではなく)ファイル内にある場合、csh
(または他のシェル)からは、これを実行する以外は何も必要ありません。
% awk '{printf("%.15f\n", $1*1e3)}' <file
上記と同じ精度の制限が適用されます。
[a] 実際には、技術的に正確にするために、最初に%g
printf形式で桁数を制限する必要があります。そのため、明確な解決策は3レベルの変換です。
妥当なシェル(ksh、bash、zsh)では、これは機能します。
$ bash -c 'printf "%.15f\n" "$(printf "%.18f" "$( printf "%.18g" "42.53e-12")" )e3"'
0.000000042530000
しかし、二重の` `
を引用するとcshでは実際に扱いにくくなり、cshはset
を使用して変数に割り当てます。つまり、これはcsh
で機能します。
$ csh -c 'set a=`printf "%.18g" "42.53e-12"`; set a=`printf "%.18f" "$a"`; printf "%.18f\n" "${a}e3"'
0.000000042530000000
しかし、私は本当に、本当に! cshは避けてください。
最善の解決策とは言えないかもしれませんが、少しハックするだけでなんとかできました。あなたはこのようなことをすることができます-
scientific='42.53e-12'
base=$(echo $scientific | cut -d 'e' -f1)
exp=$(($(echo $scientific | cut -d 'e' -f2)*1))
converted=$(bc -l <<< "$base*(10^$exp)")
>> .00000000004253000000
以下を試すことができます:
echo "3.0000000000e+02" | awk '{printf("%d",$0);}'
または小数があると予想される場合
echo ""3.676361000e+02" | awk '{printf("%0.2f",$0);}'