【问题标题】:Shell loops using non-integers?使用非整数的外壳循环?
【发布时间】:2011-01-29 03:43:02
【问题描述】:

我编写了一个 .sh 文件来编译和运行一些用于家庭作业的程序。我在脚本中有一个“for”循环,但除非我只使用整数,否则它不会起作用:

#!/bin/bash
for (( i=10; i<=100000; i+=100))
do
    ./hw3_2_2 $i
done

变量 $i 是程序 hw3_2_2 的输入,我想使用非整数值。如何循环运行带有十进制数字列表的代码?

【问题讨论】:

    标签: bash scripting loops sh


    【解决方案1】:

    这是另一种方式。您可以使用此处的文档将您的数据包含在脚本中:

    read -r -d '' data <<EOF
    1.1
    2.12
    3.14159
    4
    5.05
    EOF
    
    for i in "$data"
    do
        ./hw3_2_2 "$i"
    done
    

    同样:

    array=(
    1.1
    2.12
    3.14159
    4
    5.05
    )
    
    for i in "${array[@]}"
    do
        ./hw3_2_2 "$i"
    done
    

    【讨论】:

      【解决方案2】:

      我通常也使用“seq”作为第二个答案,但只是为了给出一个精确稳健整数循环的答案,然后 bc 转换为浮点数:

      #!/bin/bash 
      
      for i in {2..10..2} ; do 
        x=`echo "scale=2 ; ${i}/10" | bc`
        echo $x
      done
      

      给予:

      .2 .4 .6 .8 1.0

      【讨论】:

        【解决方案3】:

        令我感到惊讶的是,五年来没有人提到为生成范围而创建的实用程序,但话说回来,它来自 2005 年左右的 BSD,也许当时它甚至还没有在 Linux 上普遍可用提出了问题。

        但这里是:

        for i in $(seq 0 0.1 1)
        

        或者,要打印具有相同宽度的所有数字(通过添加或添加零),请使用-w。这有助于防止数字以“整数”形式发送,如果这会导致问题。

        语法为seq [first [incr]] lastfirst 默认为 1,incr 默认为 1 或 -1,具体取决于 last 是大于还是小于 first。其他参数见seq(1)

        【讨论】:

        • 嗨丹尼尔,有没有办法在 for 循环中增加这个 x.x.x ?例如 for i in $(seq 1.0.20 0.0.1 1.0.24)。或者有没有办法增加这个版本#并将它添加到一个列表中,以便我可以在 for 循环中使用它?谢谢!
        【解决方案4】:

        最简单的方法是列出它们:

        for a in 1.2 3.4 3.11 402.12 4.2 2342.40
        do
          ./hw3_2_2 $a
        done
        

        如果列表很大,因此您不能将其作为文字列表,请考虑将其转储到文件中,然后使用类似

        for a in $(< my-numbers.txt)
        do
          ./hw3_2_2 $a
        done
        

        $(cat 命令。

        【讨论】:

        • cat 的无用使用。在 Bash 中:$(&lt; file),在 sh(和 Bash)中:while read a; do ...; done &lt; file
        【解决方案5】:

        您可以使用 awk 生成小数,例如0.1 的步数

        num=$(awk 'BEGIN{for(i=1;i<=10;i+=0.1)print i}')
        for n in $num
        do
          ./hw3_2_2 $n
        done
        

        或者你可以完全在 awk 中完成

        awk 'BEGIN{cmd="hw3_2_2";for(i=1;i<=10;i+=0.1){c=cmd" "i;system(cmd) } }'
        

        【讨论】:

        • 在这样的循环中使用浮点是不好的做法,因为如果你不断将 0.1 加到 1,你永远不会达到 10。计数器将从 9.9999999999999822 变为 10.099999999999982。
        • 你试过了吗?请尝试然后告诉我它是否会达到 10。
        • 如果您将&lt;=10 更改为&lt;10,您会期望输出发生变化,对吧?是吗?
        • 期望输出改变是什么意思?无论您输入&lt; 还是&lt;=,它都会停止。
        • 这里的问题是不精确表示的步骤和精确表示的步骤之间的不一致:如果使用&lt;10而不是&lt;=10,那么0.1的步骤将得到10,但不会像0.125 这样的步骤得到它,但是,如果我们使用小数,我们会在两种情况下都避免 10,正如运算符 &lt; 所暗示的那样。
        【解决方案6】:

        bash 不做十进制数。要么使用bc 之类的东西,要么转向更完整的编程语言。不过要小心accuracy problems

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-03-17
          • 2021-11-24
          • 2014-02-21
          • 1970-01-01
          • 1970-01-01
          • 2016-06-04
          • 2012-11-23
          • 1970-01-01
          相关资源
          最近更新 更多