2

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

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
4

2 回答 2

1

因此,使用现代(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"
}

(变量名称很奇怪,以减少与调用函数发生冲突的机会;如果要求将内容加载到名为ROWor的变量中,您给出的其他答案将有问题line,例如,因为它们将引用局部变量而不是全球性的描述他们的目的地)。


与 bash 3.2(Apple 发布的旧版本)兼容的类似机制,避免了与内部循环相关的性能损失和与 glob 扩展相关的错误(请参阅您的原始代码对包含*! 的行做了什么)如下:

load_array() {
  local -a _load_array__array=( )
  local -a _load_array__line
  while read -r -a _load_array__line; do
    _load_array__array+=( "${_load_array__line[@]}" )
  done <"$1"
  eval "$2=( \"\${_load_array__array[@]}\" )"
}
于 2014-11-21T01:41:25.103 回答
1

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

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

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

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

eval "$ROW[\$i]=\$word"
于 2014-11-20T20:47:50.387 回答