我想使用一个变量说:
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]}"
。