Bash从外部文件读取数组

jmi*_*zas 4 bash

我已经设置了一个Bash菜单脚本,也需要用户输入.这些输入被写入(附加)一个名为var.txt的文本文件,如下所示:

input[0]='192.0.0.1'
input[1]='username'
input[2]='example.com'
input[3]='/home/newuser' 
Run Code Online (Sandbox Code Playgroud)

现在我想要完成的是能够从脚本中读取var.txt,如下所示:

useradd var.txt/${input[1]}
Run Code Online (Sandbox Code Playgroud)

现在我知道只是用它来做一个例子.

乔,先谢谢你

the*_*lfe 14

使用bash的readarray声明.(这是我可以找到动态地在数组元素中放置空格的唯一方法.)你需要你的var.txt文件只包含数组的元素,每行一个,不包含赋值语句.

readarray -t input < var.txt
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请尝试help readarray(然后会告诉您尝试help mapfile).

这是我的测试:

echo -e "a\nb c\nd" > var.txt
readarray input < var.txt 
for item in "${input[@]}"; do echo $item; done
Run Code Online (Sandbox Code Playgroud)

打印:

a
b c
d
Run Code Online (Sandbox Code Playgroud)

注意:做cat var.txt | readarray -t input不起作用.我认为这是因为input变量的范围超出了范围.


thk*_*ala 6

如果整个var.txt文件中包含你只表示猛砸兼容的变量赋值,你可能只是能够采购它,使这些变量可以在一个新的bash脚本:

source var.txt

useradd ${input[1]}
Run Code Online (Sandbox Code Playgroud)

但是,这将覆盖具有相同名称的任何现有变量.通过选择特定变量,可以使用命令替换来避免这种情况:

input[1]="$(grep '^input\[1\]=' var.txt | sed "s|[^=]*='\(.*\)'|\1|")"
Run Code Online (Sandbox Code Playgroud)

它允许重命名变量,但您必须为每个感兴趣的变量执行此操作.它本质上从var.txt文件中提取变量的值,并将其赋值给一个新变量.有关其使用的更多信息,请参阅grep手册页sed信息页.

进程替换可以允许更简单的表达式:

source <(grep '^input\[[0-9]*\]=' var.txt)

useradd ${input[1]}
Run Code Online (Sandbox Code Playgroud)

这将允许您仅导入感兴趣的定义,但您必须注意不需要的变量覆盖.


Pau*_*ce. 3

您可以将变量提取封装在函数中,并利用declare在函数内部使用时创建局部变量的事实。这种技术在每次调用函数时都会读取文件。

readvar () {
    # call like this: readvar filename variable
    while read -r line
    do
        # you could do some validation here
        declare "$line"
    done < "$1"
    echo ${!2}
}
Run Code Online (Sandbox Code Playgroud)

给定一个名为“data”的文件,其中包含:

input[0]='192.0.0.1'
input[1]='username'
input[2]='example.com'
input[3]='/home/newuser'
foo=bar
bar=baz
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

$ a=$(readvar data input[1])
$ echo "$a"
username
$ readvar data foo
bar
Run Code Online (Sandbox Code Playgroud)

这将读取一个数组并重命名它:

readarray () {
    # call like this: readarray filename arrayname newname
    # newname may be omitted and will default to the existing name
    while read -r line
    do
        declare "$line"
    done < "$1"
    local d=$(declare -p $2)
    echo ${d/#declare -a $2/declare -a ${3:-$2}};
}
Run Code Online (Sandbox Code Playgroud)

例子:

$ eval $(readarray data input output)
$ echo ${output[2]}
example.com
$ echo ${output[0]}
192.0.0.1
$ eval $(readarray data input)
$ echo ${input[3]}
/home/newuser
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您只需调用该函数一次,整个数组就可用,而不必进行单独的查询。