7

科学的記数法で格納されている数値を浮動小数点の小数に変換したいので、データに対していくつかの比較を実行できます。これはbashスクリプトで実行されています-コードの小さなスニペットは次のとおりです。

while read track_id landfall_num gate_id pres_inter
do
  if [[ $landfall_num == 0001 ]]
  then
     start_flag = true
     echo DING DING $start_flag
     if [[ $pres_inter < 97000 ]]
     then
        echo Strong Storm From North $track_id, $gate_id, $pres_inter
     fi
  fi
done < $file

私の問題は、<オペランドが基本的にすべての圧力値を選択していることです。これらの値は、を使用すると科学的記数法で保存され、を使用すると選択され<ません>。私はミリバールではなくパスカルで大気圧の測定値を見ています。

出力例は次のとおりです。

Strong Storm From North 0039988 0017 1.0074E+05

Strong Storm From North 0037481 0018 9.9831E+04

これらの嵐はどちらも選択基準を満たしてはなりません!

4

3 に答える 3

7

まず第一に、bash は浮動小数点演算を使用して演算を行うことができません。2 番目に、bash は科学的表記法を認識していません (整数についても)。

最初に試すことができるのは、すべての数値が整数であることが絶対に確実である場合: それらを 10 進数表記に変換することprintfです: 喜んでそれを行います:

printf -v pres_inter "%.f" "$pres_inter"

(%.f最も近い整数に丸めます)。

次に、bash の演算を使用します。

if (( pres_inter < 97000 )); then ....

このソリューションは素晴らしく、外部コマンドやサブシェルを一切使用しません: 速度と効率です!

非整数を扱っている場合bcは、算術を行うために使用したほうがよいでしょう: しかし、bcは遅れており、科学表記法をうまく扱えないため、とにかく数値を 10 進数表記に変換する必要があります。したがって、次のようなことを行う必要があります。

printf -v pres_inter "%f" "$pres_inter"
if (( $(bc -l <<< "$pres_inter<97000") )); then ...

もちろん、これはbc. 整数に満足している場合は、最初に示した可能性に固執してください。

終わり!

于 2012-12-11T18:53:40.963 に答える
2

数値比較には、以下を使用する必要があります。

  • -eqそれ以外の==
  • -neそれ以外の!=
  • -ltそれ以外の<
  • -leそれ以外の<=
  • -gtそれ以外の>
  • -geそれ以外の>=

そして、いくつかの構文の問題を修正するには:

while read track_id landfall_num gate_id pres_inter
do
  landfall_num=$(printf "%f", "$landfall_num")
  if [[ "$landfall_num" -eq 1 ]]
  then
     start_flag="true"
     echo "DING DING $start_flag"
     if [[ "$pres_inter" -lt 97000 ]]
     then
        echo "Strong Storm From North $track_id, $gate_id, $pres_inter"
     fi
  fi
done < "$file"

更新しました:

これは、科学的記数法の数値を整数に変換する方法です。

printf "%.0f\n", 1.0062E+05

たとえば、次のように印刷します。

100620

など:

landfall_num=$(printf "%f", "$landfall_num")

landfall_num科学的記数法から通常の10進整数に変換されます。

于 2012-12-11T18:44:03.907 に答える