浮動小数点変数を整数と比較したい。これはbashで行うには最適ではないことは知っていますが、スクリプト全体はすでにbashで書かれています。 $ numberは任意の整数です。 50以下の場合、output1が必要です。他のすべての場合は、他の変数kの出力が必要です。これは私がこれまでに持っているものです:
number=43
test=$(echo "scale=2; $number/50" | bc -l)
echo "$test"
for k in {1..5}
do
if ["$test" -le 1]
then echo "output"
Elif ["$test" -gt $k]
then echo "output$k"
fi
done
Test = 0.43で試してみると、最初のループは機能しません。整数と浮動小数点の比較に関係していると思いますが、機能させることはできません。
私が不足しているものは何ですか?
PS:this [0.43: command not found
は端末が出力するものです。
Bashはフロートを処理できません。代わりにbc
にパイプします。
if [ $(echo " $test > $k" | bc) -eq 1 ]
ただし、表示されるエラーは、test
コマンド(つまり、[
)の前後にスペースが必要なためです。
次のような数値を比較するので、(( ... ))
を使用することはさらに優れています。
if (( $(bc <<< "$test > $k") ))
ループ内の部分は次のようになります。
if (( $(bc <<< "$test <= 1") ))
then
echo "output"
Elif (( $(bc <<< "$test > $k") ))
then
echo "output$k"
fi
関係式は、関係が偽の場合は0、関係が真の場合は1に評価されます[ source ]。ただし、これはGNU bc
の動作であり、POSIX
に準拠していません。
昔の質問のようなものですが、追加の答えがあります。
高精度の電卓(bcまたはdc)へのパイピングは機能しますが、これらの電卓はbashに組み込まれていないため、フォークと余分なプロセスが必要になります。 ISに組み込まれているものの1つはprintf
です。したがって、特定の小数点以下の桁数に対処できる場合は、浮動小数点を "偽造"できます。次のような関数との比較:
#!/usr/bin/env bash
function [[[ () {
local LANG=C lhs rhs
printf -v lhs '%07.3f' "$1"; lhs=${lhs/./}
printf -v rhs '%07.3f' "$3"; rhs=${rhs/./}
case "$2" in
-lt) return $(( ! ( 10#$lhs < 10#$rhs ) )) ;;
-le) return $(( ! ( 10#$lhs <= 10#$rhs ) )) ;;
-eq) return $(( ! ( 10#$lhs == 10#$rhs ) )) ;;
-ge) return $(( ! ( 10#$lhs >= 10#$rhs ) )) ;;
-gt) return $(( ! ( 10#$lhs > 10#$rhs ) )) ;;
esac
}
number=${1:-43}
test=$(dc -e "2k $number 50 / p")
echo "$test"
for k in {1..5}; do
if [[[ "$test" -le 1 ]]]; then
echo "output"
Elif [[[ "$test" -gt "$k" ]]]; then
echo "output $k"
fi
done
ここで考慮すべきことがいくつかあります。
[[[
と名付けました。好きな名前を付けることができます。 ntest
またはmynumericcomparison
または[[[
。printf
はbash内の内部関数であるため、パス上にあるにもかかわらず、フォークの費用はかかりません。printf
形式を調整します。case
ステートメント内の各変数の先頭にある10#
は、ゼロが埋め込まれた数値が8進数として解釈される可能性があるため、10を基数とする比較を強制します。