-1

在下面的代码中,ShellCheckwhile在子句中引发错误。

count=10.0
while [ $count -le 20.0 ]
do
    echo "Hello"
    count=$(bc<<< "scale=4; (count+0.1)")
done

ShellCheck 说:

不支持小数,使用整数或 bc

我不太确定如何在while循环中使用 bc 。

while [ $(bc <<< "scale=4; (count -le 20.0)" ]

如何比较while子句中的十进制数?有什么建议吗?

4

3 回答 3

4

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
于 2015-07-12T22:53:21.987 回答
1

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

于 2015-07-12T20:31:57.593 回答
0

虽然 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。如您的示例所示,序列为包含所以 FIRST 和 LAST 都将产生,前提是 INCREMENT 均分 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)

笔记

  1. seq不是 Posix,但它几乎总是存在;它是 GNU coreutils 和类似实用程序的一部分,在 Mac OS X 中可用)自 3.0 以来已在 NetBSD 中,自 9.0 以来已在 FreeBSD 中。
于 2015-07-12T21:03:05.717 回答