在 Bash while 循环中比较小数
Compare Decimals in Bash while Loop
在下面的代码中,ShellCheck 在 while
子句中抛出错误。
count=10.0
while [ $count -le 20.0 ]
do
echo "Hello"
count=$(bc<<< "scale=4; (count+0.1)")
done
ShellCheck 说:
Decimals not supported, either use integers or bc
我不太确定如何在 while
循环中使用 bc。
while [ $(bc <<< "scale=4; (count -le 20.0)" ]
如何比较 while 子句中的小数?有什么建议吗?
Bash 不支持浮点运算。您也可以使用 bc
进行比较:
count=10.0
while : ;
do
out=$(bc -l<<< "$count<20.0")
[[ $out == 0 ]] && { echo "Reached limit" ; exit 0; }
echo "Hello"
count=$(bc<<< "scale=4; ($count+0.1)")
done
请注意,我在更新 count
的循环中将缺失的 $
添加到 count
。
虽然 bash 不处理浮点数,但 seq
实用程序可以。 [注1]
基本语法是seq FIRST INCREMENT LAST
,所以在你的情况下你可以使用
for count in "$(seq 10.0 0.1 20.0)"; do
# something with $count
done
如果您提供两个参数,则假定它们是 FIRST 和 LAST,INCREMENT 为 1。如果您只提供一个参数,则假定它们是 LAST,FIRST 和 INCREMENT 都为 1。如您的例如,序列是 inclusive 所以如果 INCREMENT 平均除以 FIRST−LAST.
,那么将生成 FIRST 和 LAST。
您还可以包含明确的格式:
$ seq -f "%06.3f" 1 .5 2
01.000
01.500
02.000
此技术的一个缺点是它会预先计算整个值集合。如果循环将执行数十万次,那可能会占用大量内存,在这种情况下,您可以改用管道或进程替换:
while read count; do
# something with count
done < <(seq 10.0 0.000001 20.0)
备注
seq
不是 Posix 但它几乎总是存在;它是 GNU coreutils 和类似实用程序的一部分,可在 Mac OS X) NetBSD 3.0 和 FreeBSD 9.0 中使用。
Bash 不支持浮点运算。
您可以使用 bc:
count="10.0"
limit="12.0"
increment="0.1"
while [ "$(bc <<< "$count < $limit")" == "1" ]; do
echo "Hello"
count=$(bc <<< "$count+$increment")
done
或 awk:
while awk 'BEGIN { if ('$count'>='$limit') {exit 1}}'; do
echo "Hello"
count=$(bc <<< "$count+$increment")
done
我只是想知道:为什么不(直接)从 10.0 数到 12.0?
for i in $(seq 10.0 0.1 12.0); do
echo "Hello"
done
在下面的代码中,ShellCheck 在 while
子句中抛出错误。
count=10.0
while [ $count -le 20.0 ]
do
echo "Hello"
count=$(bc<<< "scale=4; (count+0.1)")
done
ShellCheck 说:
Decimals not supported, either use integers or bc
我不太确定如何在 while
循环中使用 bc。
while [ $(bc <<< "scale=4; (count -le 20.0)" ]
如何比较 while 子句中的小数?有什么建议吗?
Bash 不支持浮点运算。您也可以使用 bc
进行比较:
count=10.0
while : ;
do
out=$(bc -l<<< "$count<20.0")
[[ $out == 0 ]] && { echo "Reached limit" ; exit 0; }
echo "Hello"
count=$(bc<<< "scale=4; ($count+0.1)")
done
请注意,我在更新 count
的循环中将缺失的 $
添加到 count
。
虽然 bash 不处理浮点数,但 seq
实用程序可以。 [注1]
基本语法是seq FIRST INCREMENT LAST
,所以在你的情况下你可以使用
for count in "$(seq 10.0 0.1 20.0)"; do
# something with $count
done
如果您提供两个参数,则假定它们是 FIRST 和 LAST,INCREMENT 为 1。如果您只提供一个参数,则假定它们是 LAST,FIRST 和 INCREMENT 都为 1。如您的例如,序列是 inclusive 所以如果 INCREMENT 平均除以 FIRST−LAST.
,那么将生成 FIRST 和 LAST。您还可以包含明确的格式:
$ seq -f "%06.3f" 1 .5 2
01.000
01.500
02.000
此技术的一个缺点是它会预先计算整个值集合。如果循环将执行数十万次,那可能会占用大量内存,在这种情况下,您可以改用管道或进程替换:
while read count; do
# something with count
done < <(seq 10.0 0.000001 20.0)
备注
seq
不是 Posix 但它几乎总是存在;它是 GNU coreutils 和类似实用程序的一部分,可在 Mac OS X) NetBSD 3.0 和 FreeBSD 9.0 中使用。
Bash 不支持浮点运算。 您可以使用 bc:
count="10.0"
limit="12.0"
increment="0.1"
while [ "$(bc <<< "$count < $limit")" == "1" ]; do
echo "Hello"
count=$(bc <<< "$count+$increment")
done
或 awk:
while awk 'BEGIN { if ('$count'>='$limit') {exit 1}}'; do
echo "Hello"
count=$(bc <<< "$count+$increment")
done
我只是想知道:为什么不(直接)从 10.0 数到 12.0?
for i in $(seq 10.0 0.1 12.0); do
echo "Hello"
done