将变量名称作为参数传递给bash中的函数

时间:2014-11-20 19:49:45

标签: bash param variable-names

我正在尝试将不同名称的3个类似文件读取到不同的数组中。因为我不想使用不必要的代码,所以我试图创建可以接受数组名称为params的函数,但是我收到错误'命令找不到'。

hello.sh文件代码:

    #!/bin/bash
declare -a row_1
declare -a row_2
declare -a row_3


load_array()
{
ROW="$2"
let i=0
while read line; do
    for word in $line; do
    $ROW[$i]=$word        
((++i))
    done
done < $1
}

load_array $1 row_1
load_array $2 row_2
load_array $3 row_3

使用以下代码从终端调用此文件:sh hello.sh 1.txt 2.txt 3.txt

我得到的错误列表:

hello.sh: line 13: row_1[0]=9: command not found
hello.sh: line 13: row_1[1]=15: command not found
hello.sh: line 13: row_1[2]=13: command not found
hello.sh: line 13: row_2[0]=12: command not found
hello.sh: line 13: row_2[1]=67: command not found
hello.sh: line 13: row_2[2]=63: command not found
hello.sh: line 13: row_3[0]=75: command not found
hello.sh: line 13: row_3[1]=54: command not found
hello.sh: line 13: row_3[2]=23: command not found

2 个答案:

答案 0 :(得分:1)

在赋值语法中,等号左边的内容必须是变量名(分配给标量时),或变量名后跟方括号中的单词(分配给数组元素时) 。在您的代码中,$ROW[$i]=$word与此语法不匹配(开头有$,因此它可能不是一个分配);它恰好包含一个字符=

在bash中,您可以使用declare内置来分配一个名称是某些计算结果的变量,例如变量扩展。请注意,与直接赋值不同,您需要在值部分周围使用双引号,以防止在$word上进行单词拆分和文件名扩展。如果您正在函数中执行赋值,并且希望在函数返回后保留该值,则传递选项-g

declare -g $ROW[$i]="$word"

如果您正在运行没有declare -g的旧版本的bash,则可以使用eval。这将是用于在plain sh中分配动态命名变量的方法。注意正确引用:如果ROW是例如row_1,然后作为参数传递给eval的字符串必须是row_1[$i]=$word(用于解析和执行的shell命令)。

eval "$ROW[\$i]=\$word"

答案 1 :(得分:0)

使用现代(bash 4.3+)语法执行此操作的理想方法是:

load_array() {
  declare -n _load_array__row=$2
  declare -a _load_array__line
  _load_array__row=( )
  while read -r -a _load_array__line; do
    _load_array__row+=( "${_load_array__line[@]}" )
  done <"$1"
}

(变量名称为奇数以减少与调用函数冲突的可能性;如果要求将内容加载到名为ROW或{{1的变量中的内容中,则您给出的其他答案将会有问题例如,因为他们在描述目的地时会引用局部变量而不是全局变量。


与bash 3.2(Apple发布的古老版本)兼容的类似机制,避免了与内部循环相关的性能损失以及与glob扩展相关的错误(请参阅原始代码对包含line的行所执行的操作!)如下:

*