问题描述
我想从bash脚本的txt文件中读取变量名。
例如
我在终端机上运行var="thanks"
我创建了file.txt,而txt文件包含$var
我在终端中创建变量var2
。 var2=""
然后,我在终端中运行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!
它的优点:
- 您可以填充任何类型的变量,例如关联数组的数组
- 您可以在同一函数中填充许多变量