在 BASH 数学脚本中使用 Python 的替代方法
Alternative to using Python in a BASH script for math
我正在编写 BASH 脚本。我有一个设置为以下代码的变量:
VAR="$(python -c "print (-$STEP+0.25) > ($OLD_OUTPUT_POWER - $NEW_OUTPUT_POWER) > (-$STEP-0.25)")"
其中STEP
为10-1之间的整数,OLD_OUTPUT_POWER
和NEW_OUTPUT_POWER
为小数(即:-14.3498306270)。我熟悉 Python,并希望在 BASH 中严格执行以下操作:
if ((-$STEP+0.25) > ($OLD_OUTPUT_POWER - $NEW_OUTPUT_POWER) > (-$STEP-0.25)); then
blah blah
基本上如果是真的,那就去做。
我现在的做法是这样的:
VAR="$(python -c "print (-$STEP+0.25) > ($OLD_OUTPUT_POWER - $NEW_OUTPUT_POWER) > (-$STEP-0.25)")"
if [[ $VAR == "True" ]]; then
echo "True"
fi
但是我希望能够在不使用 Python 的情况下做到这一点。有什么想法吗?
提前致谢:)
如果小数点很重要,则使用 bc
否则使用 bash 扩展名 $((ANARITHMETICEXPRESSION))
.
shell 本身没有进行浮点运算的可移植方法。您将需要求助于外部程序。
您可以使用 AWK 而不是 Python,它的开销明显较小。请注意,它不理解 Python 花哨的 x < y < z
语法,因此您必须将其重写为 x < y && y < z
。您可以定义这个 Bash 函数。
## usage: is_between VALUE UPPER LOWER
##
## Checks whether VALUE is truly between UPPER and LOWER.
##
function is_between {
awk "BEGIN { exit(!( < && < )); }"
}
它将 return 通过其退出状态给出答案,因此可以直接在条件语句中使用。例如:
value=3.15
lower=3.14
upper=3.16
if is_between $value $lower $upper
then
echo "$value is in ($lower, $upper)"
else
echo "$value is not in ($lower, $upper)"
fi
我写了一个小基准。请注意,我实际上是在比较整数,而不是实数,因此我可以与 shell 内置函数进行比较。
#!/bin/sh -eu
what=
if [ ${#} -gt 0 ]
then
what=
fi
case $what in
awk)
function is_between {
awk "BEGIN { exit(!( < && < )); }"
}
;;
python)
function is_between {
python -c "import sys; sys.exit(not ( < < ));"
}
;;
*)
# This one only works for integers!
function is_between {
return $((!( < && < )))
}
;;
esac
i=0
count=0
while [ $i -lt 1000 ]
do
value="$RANDOM"
lower="$RANDOM"
upper="$RANDOM"
if is_between $value $lower $upper
then
count=$(($count + 1))
fi
i=$(($i + 1))
done
echo "$count values were in between"
这是我的计时结果:
$ time ./test.sh
152 values were in between
real 0m0.055s
user 0m0.053s
sys 0m0.000s
$ time ./test.sh python
146 values were in between
real 0m33.354s
user 0m27.570s
sys 0m4.047s
$ time ./test.sh awk
157 values were in between
real 0m5.486s
user 0m3.503s
sys 0m0.723s
如您所见,差异非常显着……
我正在编写 BASH 脚本。我有一个设置为以下代码的变量:
VAR="$(python -c "print (-$STEP+0.25) > ($OLD_OUTPUT_POWER - $NEW_OUTPUT_POWER) > (-$STEP-0.25)")"
其中STEP
为10-1之间的整数,OLD_OUTPUT_POWER
和NEW_OUTPUT_POWER
为小数(即:-14.3498306270)。我熟悉 Python,并希望在 BASH 中严格执行以下操作:
if ((-$STEP+0.25) > ($OLD_OUTPUT_POWER - $NEW_OUTPUT_POWER) > (-$STEP-0.25)); then
blah blah
基本上如果是真的,那就去做。
我现在的做法是这样的:
VAR="$(python -c "print (-$STEP+0.25) > ($OLD_OUTPUT_POWER - $NEW_OUTPUT_POWER) > (-$STEP-0.25)")"
if [[ $VAR == "True" ]]; then
echo "True"
fi
但是我希望能够在不使用 Python 的情况下做到这一点。有什么想法吗?
提前致谢:)
如果小数点很重要,则使用 bc
否则使用 bash 扩展名 $((ANARITHMETICEXPRESSION))
.
shell 本身没有进行浮点运算的可移植方法。您将需要求助于外部程序。
您可以使用 AWK 而不是 Python,它的开销明显较小。请注意,它不理解 Python 花哨的 x < y < z
语法,因此您必须将其重写为 x < y && y < z
。您可以定义这个 Bash 函数。
## usage: is_between VALUE UPPER LOWER
##
## Checks whether VALUE is truly between UPPER and LOWER.
##
function is_between {
awk "BEGIN { exit(!( < && < )); }"
}
它将 return 通过其退出状态给出答案,因此可以直接在条件语句中使用。例如:
value=3.15
lower=3.14
upper=3.16
if is_between $value $lower $upper
then
echo "$value is in ($lower, $upper)"
else
echo "$value is not in ($lower, $upper)"
fi
我写了一个小基准。请注意,我实际上是在比较整数,而不是实数,因此我可以与 shell 内置函数进行比较。
#!/bin/sh -eu
what=
if [ ${#} -gt 0 ]
then
what=
fi
case $what in
awk)
function is_between {
awk "BEGIN { exit(!( < && < )); }"
}
;;
python)
function is_between {
python -c "import sys; sys.exit(not ( < < ));"
}
;;
*)
# This one only works for integers!
function is_between {
return $((!( < && < )))
}
;;
esac
i=0
count=0
while [ $i -lt 1000 ]
do
value="$RANDOM"
lower="$RANDOM"
upper="$RANDOM"
if is_between $value $lower $upper
then
count=$(($count + 1))
fi
i=$(($i + 1))
done
echo "$count values were in between"
这是我的计时结果:
$ time ./test.sh
152 values were in between
real 0m0.055s
user 0m0.053s
sys 0m0.000s
$ time ./test.sh python
146 values were in between
real 0m33.354s
user 0m27.570s
sys 0m4.047s
$ time ./test.sh awk
157 values were in between
real 0m5.486s
user 0m3.503s
sys 0m0.723s
如您所见,差异非常显着……