Bash参数数组操作问题

时间:2012-04-14 23:31:30

标签: bash

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

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

echo ${modifiedNames[1]}

例如,如果我这样调用我的脚本:./ script.sh file1 file2我得到file1 [file1hash]

提前致谢!

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

您正在遍历从0开始的arguments数组,这是命令名称。因此,如果您将脚本称为./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

答案 2 :(得分:1)

$@不是真正的数组 - 它是一个shell“特殊参数”,你需要比其他数组更加小心。

您所看到的行为的原因是,当${parameter:length:offset}parameter时,@语法的确切行为是特殊的,并且行为与如果@是一个真正的数组,你会得到的行为。

以下是相关文档(粗体强调我的):

  

${ 参数 : 偏移 : 长度 }

     

...如果参数是@,则结果为长度 位置参数,从偏移量开始。如果参数为@,则结果为 length 位置参数,从 offset 开始。 ...

位置参数$0$1$2,...,因此使用此语法时,其行为就像包含$@一样脚本名称($0)以及脚本的参数($1$2,...)。这与"$@"扩展到"$1" "$2" ...不一致,但这就是生命。

你应该能够通过创建一个新数组来简化事情(并修复脚本),而不是直接使用$@,即

new_array=("$@")
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]}

答案 3 :(得分:0)

实际上, 获取第二个元素,但是你的循环在[0]和[1]中放置相同的值。

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

n=0
for i in "$@"; do
  . . .
  n=$(($n + 1))
done