【问题标题】:Dynamic beginning of for loopfor循环的动态开始
【发布时间】:2019-12-25 19:17:12
【问题描述】:

使用两个替代开始创建 bash for 循环。我想根据条件遍历范围内的所有数字或数组中的所有元素。以下非正统代码显示了示例:

#!/bin/bash
FROMVAL=1
TOVAL=5
VALARR=(1 3 5)
ISCONSEQ=1
if (( ISCONSEQ == 1 )); then
        for (( counter=$FROMVAL; counter<=$TOVAL; counter++ ))
else
        for counter in "${VALARR[@]}"
fi
        do
                echo $counter
        done

显然,这不起作用,也不是很漂亮。有没有一种 bash 方法可以做到这一点,或者我应该创建两个 for 循环并根据ISCONSEQ 的内容只执行一个循环?或者我应该对这两种情况都使用for...in 循环并简单地将我的序列的值分配给数组?

此代码确实有效,但仅依赖于数组:

if (( ISCONSEQ == 1 )); then
        VALARR=($(seq $FROMVAL 1 $TOVAL))
fi
for counter in "${VALARR[@]}"
do
        echo $counter
done

【问题讨论】:

标签: bash for-loop conditional-statements


【解决方案1】:

这是一个很好的函数用例。为 echo 创建函数并从每个 for 循环中调用它。它看起来像这样。

#!/bin/bash
FROMVAL=1
TOVAL=5
VALARR=(1 3 5)
ISCONSEQ=1

function dostuff() {
   echo $*
}

if (( ISCONSEQ == 1 )); then
        for (( counter=$FROMVAL; counter<=$TOVAL; counter++ ))
        do
            dostuff $counter
        done
else
        for counter in "${VALARR[@]}"
        do
                dostuff $counter
        done
fi

【讨论】:

    【解决方案2】:

    首先,我同意之前的 cmets 的观点,即 2 for 循环并不像看起来那么令人反感。

    其次,您不能以示例的方式有条件地启动 for 循环。但是,您可以使用条件操作数组。

    所以为了满足您的问题,这里将是一个简单的解决方案:

    FROMVAL=1
    TOVAL=5
    VALARR=(1 3 5)
    ISCONSEQ=0
    
    if (( ISCONSEQ != 1))
    then
        VALARR=($(seq $FROMVAL 1 $TOVAL))
    fi
    
    for counter in "${VALARR[@]}"
    do
      echo "$counter"
    done
    

    【讨论】:

    • “简单”解决方案看起来非常像问题中的最后一个示例 - 你在那里改变了什么?
    • 啊!我没看到。请无视。
    • 我在原始发布后添加了最后一个示例。可能是这样。这个问题是出于好奇,因为 Bash 几乎可以向任何方向弯曲,而为了便于阅读,函数实现要好得多。也感谢您的意见。
    猜你喜欢
    • 2012-12-12
    • 2018-01-03
    • 2016-08-19
    • 2021-12-18
    • 2013-06-22
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多