从txt文件读取变量名 说明:在填充变量时避免分叉的替代方法:

问题描述

我想从bash脚本的txt文件中读取变量名。

例如

我在终端机上运行var="thanks"
我创建了file.txt,而txt文件包含$var
我在终端中创建变量var2var2=""
然后,我在终端中运行var2=$(<file.txt)命令。

问题是

$ echo $var2
"$var"

我希望echo $var命令的输出为“谢谢”

$ echo $var2
"thanks"

那我该怎么办?

解决方法

如果仅将var放入文件中而没有$和引号,则可以使用变量间接寻址。

var2=$(< file.txt)
var2=${!var2}
echo $var2

或者,如果您需要美元符号和引号,请在应用间接寻址之前使用参数扩展将其删除

var2=$(< file.txt)
var2=${var2#'"$'}
var2=${var2%\"}
var2=${!var2}
echo $var2
,

两种不同的打击方式:

1。使用${!var} 间接扩展

删除$"(如果存在)的另一种方法:

IFS='$"' read -a var2 <file.txt
var2=(${var2[*]})
echo ${!var2}

测试:

var=Hello\ world\!
echo '"$var"' >file.txt
cat file.txt 
"$var"

IFS='$"' read -a var2 <file.txt
var2=(${var2[*]})
echo ${!var2}
Hello world!

echo 'var' >file.txt 
cat file.txt 
var

IFS='$"' read -a var2 <file.txt
var2=(${var2[*]})
echo ${!var2}
Hello world!

说明:

  • IFS 输入字段分隔符(通常包含:$' \t\n' <space><tab><newline> )。该字段中的所有字符都被视为字段分隔符,因此请不要出现在 array 中。

  • IFS='..' read ..,当变量定义命令之前,变量仅对此执行受影响

  • -a var2读取使var2成为数组。使用declare -p来显示他的内容:

     IFS='$"' read -a var2 <file.txt
     declare -p var2
     declare -a var2=([0]="" [1]="" [2]="var")
    
  • ${var2[*]}var的字段合并为一个字符串,并以第一个$IFS字符分隔。

     echo "<${var2[*]}>"
     <  var>
    
  • var2=( foo bar baz )将重新定义var2,忽略空格(与$IFS中的任何字符一样)

     var2=(${var2[*]})  # This step become useless,in 2nd case,but harmless.
     declare -p var2
     declare -a var2=([0]="var")
    
  • ${!var2}被称为间接扩展

     echo ${!var2}
     Hello world!
    

2。使用参考名称: nameref

  • declare -n name=value使NAME成为对由其值命名的变量的引用

IFS='$"' read -a var2 < file.txt
var2=(${var2[*]})
declare -p var2
declare -a var2=([0]="var")

declare -n var3=$var2
echo $var3
Hello world!

这在函数中可用作local -n

readFrom() {
    local var2
    IFS='$"' read -a var2 < $1
    var2=(${var2[*]})
    local -n target=$var2
    echo $target
}

然后

echo '"$var"' >file.txt
var=Hello\ world\!
readFrom file.txt 
Hello world!

在填充变量时避免分叉的替代方法:

readFrom() {
    local var2
    IFS='$"' read -a var2 < $1
    var2=(${var2[*]})
    local -n target=$var2 result=${2:-INPUT}
    result=("$target")
}

然后

readFrom file.txt newvar
echo "$newvar"
Hello world!

它的优点:

  • 您可以填充任何类型的变量,例如关联数组的数组
  • 您可以在同一函数中填充许多变量