使用Sed扩展文件中的环境变量

时间:2009-10-22 19:26:42

标签: sed environment-variables

我想使用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"

任何人都可以对此有所了解吗?

2 个答案:

答案 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变量插值完成工作。