bash - 使用变量 int 值来引用函数中的位置参数

bash - 使用变量 int 值来引用函数中的位置参数

我想使用一个变量说:

i=1

作为引用传递给脚本的位置变量的值,例如:

x=101
y=201
z=301

foo(){
    echo "$1"
    echo "$2"
    echo "$3"
}

foo x y z

输出:

101
201
301

我如何使用i索引变量来递增,而不是通过索引引用每个参数?

澄清:

foo() {
    local i=1
    echo "$i" #echo first paramter
    (( i+=1 ))
    echo "$i" #echo second parameter
    #etc.
}

该部分的语法是什么echo "$i"

@Eric 回答后更新

~$ t=5
~$ foo() { i=1; echo "${!i}"; }
~$ foo t
t
~$

更新#2

简而言之,我可以使我的方法发挥作用的唯一方法是:

foo() { #assuming 3 parameters

    i=0
    (( i+=1 ))
    var="${!i}"
    echo "${!var}"

    (( i+=1 ))
    var="${!i}"
    echo "${!var}"

    (( i+=1 ))
    var="${!i}"
    echo "${!var}"        
}

答案1

这类似于SO问题这里,这与 @costas 评论类似。您可以使用$#来获取参数的数量,然后间接引用${!i}就像通过名称访问变量一样。这是一个例子:

f() {
    for((i=1; i<=$#; i++)); do
        printf "%d %s\n" "$i" "${!i}"
    done
}

f a b c

打印:

1 a
2 b
3 c

现在看到您想要将变量名称作为位置参数传递,您可以额外增加一层间接引用,如下所示:

a=first
b=second
c=third

f() {
    for((i=1; i<=$#; i++)); do
        var="${!i}"
        printf "%d %s\n" "$i" "${!var}"
    done
}

f a b c

打印

1 first
2 second
3 third

这让我们将每个参数视为变量的名称,并将其存储在var此处。然后我们在printf.

一次只能获得一层间接,嵌套不起作用。因此,尝试一下子完成此操作是行不通的,${!${!i}}因为第一个{开始扩展,其余部分被视为要扩展的 PARAMETER 值。第一个字符!将把其余字符视为包含我们想要的参数名称的 PARAMETER 名称,但${!i}不是有效的参数名称,因此我们得到一个bad substitution.所以我们只需分两步就可以避免这个问题。

答案2

使用shift,您可以执行以下操作:

num_args="$#"

for (( i = 1; i <= "$num_args"; i++ )); do
    echo "$1"
    shift
done

在这里,shift命令转变传递给脚本的参数中的每个下一个参数都是 的值$1

例如:

$ ./myscript one two three four five six
one
two
three
four
five
six

其中,在循环的第一次运行中,$1 = "one",然后在循环的第二次运行中,$1 = "two",依此类推,直到最后一个参数。


编辑:如果您想在没有顺序的情况下访问任何脚本参数,例如。同时使用第二个和第四个参数,一种方法是使用 bash 数组,如下所示:

# Initialize the array 'myargs' with all script arguments
myargs=( "$@" )

for (( i = 0; i < "$#"; i++ )); do
    echo "${myargs[$i]}"
done

i在这里,您可以使用表单访问具有任何指定索引的任何参数"${myargs[$i]}"

相关内容