2012-04-14 54 views
4

我的第一个bash脚本有问题。我在for循环中填充一个数组,并且当我尝试从它获取一个项目时,我总是得到第一个元素。Bash参数数组操作问题

for ((i = 0; i < ${#*}; i++)); do 
hash=$(md5 -q ${@:$i:1}) 
modifiedNames[$i]=${@:$i:1}$hash 
done 

echo ${modifiedNames[1]} 

例如,如果我把我的脚本是这样的:./script.sh文件1文件2,我收到文件1 [file1hash]

提前感谢!

回答

1

[email protected] ISN”一个真正的数组 - 它是一个shell“特殊参数”,你需要比其他数组更小心。

的理由让你所看到的行为是${parameter:length:offset}语法的确切行为是特例,当parameter@,且行为与一致的行为,你会得到,如果@是一个真正的数组。

这里的相关文件(大胆重点煤矿):

${参数:偏移:长度}

...如果参数是@,将结果是长度位置参数开始于偏移量。如果参数是@,则结果是长度位置参数开始于偏移量。 ...

位置参数$0$1$2,...,所以用这样的语法它表现得好像[email protected]包含脚本名称($0),以及作为参数传递给脚本($1$2 ,...)。这与"[email protected]"扩展到"$1" "$2" ...不一致,但这就是生活。

你应该能够把事情简单化(和修复脚本),通过使新的阵列,而不是直接使用[email protected],即

new_array=("[email protected]") 
for ((i = 0; i < ${#new_array}; i++)); do 
    hash=$(md5 -q ${new_array[@]:$i:1}) 
    modifiedNames[$i]=${new_array[@]:$i:1}$hash 
done 

echo ${modifiedNames[1]} 
0

其实,你得到第二个元素,但你的循环在[0]和[1]中放置相同的值。

我不确定你在做什么,但它可能会更容易迭代参数,然后为数组保留一个单独的计数器。

n=0 
for i in "[email protected]"; do 
    . . . 
    n=$(($n + 1)) 
done 
+0

好,但为什么循环表现呢?我看不到为什么它将相同的值放入数组项。 – 2012-04-14 23:51:04

2

我认为你的循环表现得有趣,因为它应该以i = 1开始并转到i = $ {#*}。扩展$ {@:0:1}给予file1,$ {@:1:1}也是如此。

尝试for ((i = 1; i <= ${#*}; i++))

1

您通过参数数组从0开始,这是命令名迭代。所以,如果你打电话给你的脚本一样./script.sh file1 file2,则:

${@} = array(
    [0] = ./script, 
    [1] = file1, 
    [2] = file2 
) 

所以你得到:

modifiedNamed = array(
    [0] = md5(./script), 
    [1] = md5(file1) 
) 

你应该改变你的for循环索引:

for ((i = 1; i <= ${#*}; i++)); do