Bash 在 for 中跳过迭代

Bash skipping iteration in for

我必须编写一个几乎没有参数的宏。例如 ./macro.sh -wrongone -f 文件名 -wrongone。 我必须抓住错误的并列出它们并对有效的进行必要的操作。这是我的代码:

for i in "${ArrayOfParameters[@]}"
do
    tmp=$[tmp+1]
    case "${i}" in

    "-h" | "--help")
        help
        ;;

    "-f")   
        a="${ArrayOfParameters[i+1]}"
        echo $a
        i=$[i+1]            
        ;;          

    *)
        echo -e "${red}Parameter ${i} is wrong!${NC}"
        ;;
    esac

done    

我的问题是我不知道如何通过开关的默认操作跳过 'filename' :(。每次我都收到文件名参数错误的错误消息。我正在考虑跳过一个迭代。类似于 C++ 中的东西。

for(int i=0;i<5;i++)
if(i==3)
i=4;

我想在 Bash 中得到类似的东西,但不知道该怎么做。 尝试过

for (( i=0; i<=5; i++ ))
a="${ArrayOfParameters[i]}"

但它一直给我返回数字而不是字符串。 如果您能提供有用的答案,我将不胜感激。

如果我没理解错的话,你想在找到-f后跳过下一个项,对吧?如果是这种情况,您可以使用更像 C 的语法并使用数组 index,而不是数组 contents

#!/bin/bash

declare -a ArrayOfParameters=("-hello" "-howdy" "-foo bar" "-f" "-something else")

for ((i=0; i <= ${#ArrayOfParameters[@]}; i++))
do
    item=${ArrayOfParameters[i]}
    echo "Studying item number ${i} (value: ${item})"
    case "${item}" in
        "-f")   
           echo "Found -f. Skipping next."  
           ((i++))
           ;;          
        *)
           echo "NOT skipping ${item}"
           ;;
    esac
done

您会看到它跳过了 -f:

之后的项目
Studying item number 0 (value: -hello)
NOT skipping -hello
Studying item number 1 (value: -howdy)
NOT skipping -howdy
Studying item number 2 (value: -foo bar)
NOT skipping -foo bar
Studying item number 3 (value: -f)
Found -f. Skipping next.
Studying item number 5 (value: )
NOT skipping 

我认为最简单的解决方案是使用您设置为 true 的标志变量(如果“-f”匹配)并在您的 for 循环开始时检查该标志是否已设置,将其设置为false 并使用 continue.

skipNext=false
for i in "${ArrayOfParameters[@]}"
do
    if $skipNext
    then
        skipNext=false
        continue
    fi
    tmp=$[tmp+1]
    case "${i}" in
        "-h" | "--help")
            help
            ;;
        "-f")
            skipNext=true
            a="${ArrayOfParameters[i+1]}"
            echo $a
            i=$[i+1]            
            ;;
        *)
            echo -e "${red}Parameter ${i} is wrong!${NC}"
            ;;
    esac
done  

不是您编码问题的直接答案,但我认为您应该帮自己一个忙,使用 getopts(参见 here for a good tutorial)。处理参数通常很混乱,而且有很多极端情况,所以自己动手并不总是一个好主意。

我建议使用 'while' 循环。使用 'shift' 将参数指针移动到下一个参数,然后使用“$1”读取您想要的参数。您可以通过这种方式完全控制参数:

while [ $# -gt 0 ]; do
  case "" in
    -f) shift
        FILE=""
    ;;
    -h|*) help
    ;;
  esac
  shift
done