Bash脚本变量解释

时间:2012-01-25 23:24:58

标签: linux bash shell unix

我有一个文本文件,其中包含对变量的引用,并允许用户在变量周围设置他们想要的格式,例如

 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”,但是没有新行,文本中的变量也没有被值替换。

3 个答案:

答案 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