bash数组名称中的变量

时间:2014-12-28 22:22:46

标签: arrays bash

我有这段代码:

#!/bin/sh

...

for cnumber in `seq $CNUMBER`; do
    declare -a CAT$cnumber
    let i=0
    while IFS=$'\n' read -r line_data; do
        CAT$cnumber[i]="${line_data}"
        ((++i))
    done < input_file_$cnumber
done

如果我使用不带变量$ cnumber的数组名称,它就可以工作。

但我想创建多个数组(CAT0,CAT1,CAT2等)并读取行:

  

来自文件&#39; input_file_0&#39;排列&#39; CAT0&#39;
  来自档案&#39; input_file_1&#39;排列&#39; CAT1&#39;
  来自档案&#39; input_file_2&#39;阵列&#39; CAT2&#39;
  等

在数组名称(CAT1)和输入file_name中使用$cnumber变量的语法是什么?

2 个答案:

答案 0 :(得分:1)

for cnumber in `seq $CNUMBER`; do
    declare -a CAT$cnumber
    let i=0
    while IFS=$'\n' read -r line_data; do
        eval CAT$cnumber[i]='"${line_data}"'
        ((++i))
    done < input_file_$cnumber
done

主要是,增加了“#eval”和“#34;这使得bash评估其余部分。在此之前,bash扩展变量,因此当评估行时,CAT $ number将类似于CAT1。请记住&#34; $ {line_date}&#34;如果不受单引号保护,则在eval评估该行之前,它将受到变量扩展的影响。如果$ line_data包含空格,则可能会产生意外影响。请参阅此简化示例:

a=b
l="hello date"
eval $a="$l"    # executes "date", has no other effect
echo $b         # prints an empty line
eval $a='"$l"'  # sets b to "hello date"
echo $b         # prints that: hello date

在回复下面 Etan Reisner 的评论时,我添加了另一个避免&#34; eval&#34; 的解决方案,而是使用了可用的引用bash版本4.3或更高版本。在这种情况下,使用引用是优选的,因为Etan指出,而且,对我来说,因为它更自然:

for cnumber in `seq $CNUMBER`; do
    declare -a CAT$cnumber      # be sure the array is declared before ...
    declare -n ref=CAT$cnumber  # ... you declare ref to reference the array
    let i=0
    while IFS=$'\n' read -r line_data; do
        ref[$i]="${line_data}"
        ((++i))
    done < input_file_$cnumber
done

答案 1 :(得分:0)

首先,你的shebang需要

#!/bin/bash

因为declare是内置的bash。

接下来,使用declare来定义数组元素

for cnumber in `seq $CNUMBER`; do
    declare -a CAT$cnumber
    let i=0
    while IFS=$'\n' read -r line_data; do
        declare "CAT$cnumber[$i]=${line_data}"
        ((++i))
    done < input_file_$cnumber
done