我想使用Sed扩展文件中的变量。
假设我导出了一个变量VARIABLE = something,并且有一个带有以下内容的“test”文件:
I'd like to expand this: "${VARIABLE}"
我一直在尝试以下命令,但无济于事:
cat test | sed -e "s/\(\${[A-Z]*}\)/`eval "echo '\1'"`/" > outputfile
结果是“outputfile”,变量仍未展开:
I'd like to expand this: "${VARIABLE}"
但是,在bash控制台中运行eval "echo '${VARIABLE}'
会导致回显值“某事”。此外,我测试了这种模式是完全匹配的。
所需的输出是
I'd like to expand this: "something"
任何人都可以对此有所了解吗?
答案 0 :(得分:11)
考虑您的试用版:
cat test | sed -e "s/\(\${[A-Z]*}\)/`eval "echo '\1'"`/" > outputfile
这不起作用的原因是因为它需要shell的预见性。在sed匹配任何模式之前生成sed脚本,因此shell无法为您完成该任务。
我过去曾经做过几次这样的事情。通常情况下,我有一个已知变量及其值的列表,我已从该列表中进行了替换:
for var in PATH VARIABLE USERNAME
do
echo 's%${'"$var"'}%'$(eval echo "\$$var")'%g'
done > sed.script
cat test | sed -f sed.script > outputfile
如果你想任意映射变量,那么你需要处理整个环境(而不是固定的变量名列表,使用env
的输出,适当编辑),或者使用Perl或Python代替。
请注意,如果环境变量的值在您的版本中包含斜杠,则使用斜杠作为s ///表示法中的字段分隔符会遇到问题。我使用'%',因为相对较少的环境变量使用它 - 但是在某些机器上发现了一些包含'%'字符的内容,因此完整的解决方案比较棘手。您还需要担心值中的反斜杠。您可能必须使用类似“$(eval echo "\$$var" | sed 's/[\%]/\\&/g')
”的内容来转义环境变量值中的反斜杠和百分号。最后的皱纹:某些版本的sed
具有(或者有)脚本大小的有限容量 - 旧版本的HP-UX限制为大约100.我不确定这是否仍然是一个问题,但是它就在5年前。
对原始剧本的简单修改如下:
env |
sed 's/=.*//' |
while read var
do
echo 's%${'"$var"'}%'$(eval echo "\$$var" | sed 's/[\%]/\\&/g')'%g'
done > sed.script
cat test | sed -f sed.script > outputfile
但是,更好的解决方案是使用env
的输出中已有值的事实,因此我们可以写:
env |
sed 's/[\%]/\\&/g;s/\([^=]*\)=\(.*\)/s%${\1}%\2%/' > sed.script
cat test | sed -f sed.script > outputfile
这是完全安全的,因为shell永远不会评估任何不应该评估的东西 - 你必须小心使用变量值中的shell元字符。如果env
的某些输出格式不正确,我认为这个版本可能会遇到任何麻烦。
注意 - 用sed
编写sed
脚本是一种深奥的职业,但却说明了良好工具的力量。
所有这些例子都是在不清理临时文件时的疏忽。
答案 1 :(得分:6)
也许你可以不使用sed来实现:
$ echo $VARIABLE
something
$ cat test
I'd like to expand this: ${VARIABLE}
$ eval "echo \"`cat test`\"" > outputfile
$ cat outputfile
I'd like to expand this: something
让shell变量插值完成工作。