从文件填充数组

时间:2014-10-29 07:20:22

标签: arrays bash populate

我搜索了谷歌,无处找到答案。我正在获取一个函数来填充文件中的数组:

#!/bin/bash

PusherListV2=()
PusherListV3=()

getArray () {
        if ! [ -f $2 ]; then return 2
        fi
        i=0
        while read p; do
                PusherList$1[$i]="$p"
                ((i++))
        done <$2
}

getArray V2 /tmp/test.txt

echo ${PusherListV2[@]}

我遇到这种错误:

./test.sh: line 11: PusherListV2[0]=p01: command not found
./test.sh: line 11: PusherListV2[1]=p02: command not found
./test.sh: line 11: PusherListV2[2]=p03: command not found
./test.sh: line 11: PusherListV2[3]=p04: command not found
./test.sh: line 11: PusherListV2[4]=p05: command not found

有人可以帮助我吗?

3 个答案:

答案 0 :(得分:1)

您无法在赋值中使用变量替换来构造变量名称。这不起作用:

PusherList$1[$i]="$p"

替换为:

eval PusherList$1[$i]=\"\$p\"

甚至只是这个(正如shekhar suman所说,引用在这里并不特别有用):

eval PusherList$1[$i]=\$p

只要您控制$1$i,就可以安全地使用eval

答案 1 :(得分:1)

使用readarray有一个非常简单的解决方案。这是测试文件:

$ cat file.tmp
first line
second line
third line

现在我读取文件并将这些行存储在一个数组中:

$ readarray mytab < file.tmp

最后我检查一下数组:

$ declare -p mytab
declare -a mytab='([0]="first line
" [1]="second line
" [2]="third line
")'

如您所见,这些行与\n一起存储。使用-t删除它们。

现在要解决您的问题,您可以使用新的nameref属性(bash 4.3+)通过引用传递数组,不需要eval

PusherListV2=()
PusherListV3=()

getArray () array file
{
    local -n array="$1"    # nameref attribute
    local file="$2"

    test -f "$file" || return 2

    readarray -t array < "$file"
}

getArray PusherListV2 /tmp/test.txt

echo "${PusherListV2[@]}"    # always "" arround when using @

如果您仍想传递V2而不是PusherListV2,则只需撰写

    local -n array="PusherList$1"    # nameref attribute

在函数中。

答案 2 :(得分:0)

如果我理解正确,你需要一个带有两个参数的函数:

  • 第一个参数是一个字符串,将附加到PusherList以获取数组名称
  • 第二个参数是文件名

该函数应将文件的每一行放在数组中。

很简单,在Bash≥4:

getArray() {
    [[ -f $2 ]] || return 2
    # TODO: should also check file is readable
    mapfile -t "PusherList$1" < "$2"
    # TODO: check that mapfile succeeded
    # (it may fail if e.g., PusherList$1 is not a valid variable name)
}

-t的{​​{1}}选项,以便修剪尾随换行符。

注意。这很可能是最有效的方法。