我有一个文本文件,其中包含对变量的引用,并允许用户在变量周围设置他们想要的格式,例如
The date is $DATE
The time is $TIME
然后我想读取这个文本文件,替换变量,并使用bash脚本将结果打印到stdout。我得到的最接近的是使用“echo”来输出它,
DATE="1/1/2010"
TIME="12:00"
TMP=`cat file.txt`
echo $TMP
但是,输出最终都在一行上,我不希望在文本文件的每一行的末尾都有\ n。我尝试使用“cat<< $ TMP”,但是没有新行,文本中的变量也没有被值替换。
答案 0 :(得分:2)
您可以使用eval
确保在数据文件中扩展变量:
DATE="1/1/2010"
TIME="12:00"
while read line
do
eval echo ${line}
done < file.txt
请注意,这允许控制文件内容的用户执行任意命令。
如果输入文件不在您的控制之下,那么更安全的解决方案是:
DATE="1/1/2010"
TIME="12:00"
sed -e "s#\$DATE#$DATE#" -e "s#\$TIME#$TIME#" < file.txt
它假定$DATE
和$TIME
都不包含#
字符,并且不应扩展其他变量。
答案 1 :(得分:0)
比亚当的反应稍微紧凑:
DATE="1/1/2010"
TIME="12:00"
TMP=`cat file.txt`
eval echo \""$TMP"\"
所有这一切的缺点是你最终压扁了报价。更好的是使用真实的模板。我不确定如何在shell中执行此操作,因此如果可能的话,我会使用其他语言。模板的好处在于你可以消除亚当提到的那个“任意命令”漏洞,而不用像sed一样难以编写代码。
答案 2 :(得分:0)
只需引用您的变量以保留换行符。
DATE="1/1/2010"
TIME="12:00"
TMP=$(cat file.txt)
echo "$TMP"
您可以使用变量修改文件中的值 -
while read -r line
do
sed -e "s@\$DATE@$DATE@" -e "s@\$TIME@$TIME@" <<< "$line"
done < file.txt
[jaypal:~/Temp] cat file.txt
The date is $DATE
The time is $TIME
[jaypal:~/Temp] DATE="1/1/2010"
[jaypal:~/Temp] TIME="12:00"
[jaypal:~/Temp] while read -r line; do sed -e "s@\$DATE@$DATE@" -e "s@\$TIME@$TIME@" <<< "$line"; done < file.txt
The date is 1/1/2010
The time is 12:00