使用 Sed 扩展文件内的环境变量 [英] Using Sed to expand environment variables inside files

查看:31
本文介绍了使用 Sed 扩展文件内的环境变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 Sed 来扩展文件中的变量.

I'd like to use Sed to expand variables inside a file.

假设我导出了一个变量 VARIABLE=something,并且有一个包含以下内容的测试"文件:

Suppose I exported a variable VARIABLE=something, and have a "test" file with the following:

I'd like to expand this: "${VARIABLE}"

我一直在尝试类似以下的命令,但无济于事:

I've been trying commands like the following, but to no avail:

cat test | sed -e "s/(${[A-Z]*})/`eval "echo '1'"`/" > outputfile

结果是变量仍未扩展的输出文件":

The result is the "outputfile" with the variable still not expanded:

I'd like to expand this: "${VARIABLE}"

仍然,在 bash 控制台中运行 eval "echo '${VARIABLE}' 会导致值 "something" 被回显.此外,我测试过,该模式确实匹配.

Still, running eval "echo '${VARIABLE}' in bash console results in the value "something" being echoed. Also, I tested and that pattern is trully being matched.

所需的输出是

I'd like to expand this: "something"

有人能解释一下吗?

推荐答案

考虑您的试用版:

cat test | sed -e "s/(${[A-Z]*})/`eval "echo '1'"`/" > outputfile

这不起作用的原因是它需要外壳的先见之明.sed 脚本是在 sed 匹配任何模式之前生成的,因此 shell 无法为您完成这项工作.

The reason this doesn't work is because it requires prescience on the part of the shell. The sed script is generated before any pattern is matched by sed, so the shell cannot do that job for you.

我过去曾通过多种方式完成此操作.通常,我有一个已知变量及其值的列表,并且我已经从该列表中进行了替换:

I've done this a couple of ways in the past. Normally, I've had a list of known variables and their values, and I've done the substitution from that list:

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.

If you want to map variables arbitrarily, then you either need to deal with the whole environment (instead of the fixed list of variable names, use the output from env, appropriately edited), or use Perl or Python instead.

请注意,如果环境变量的值在您的版本中包含斜杠,则在使用斜杠作为 s///符号中的字段分隔符时会遇到问题.我使用了 '%',因为使用它的环境变量相对较少 - 但是在某些机器上发现了一些确实包含 '%' 字符,因此完整的解决方案更棘手.您还需要担心值中的反斜杠.您可能必须使用类似 '$(eval echo "$$var" | sed 's/[\%]/\&/g')' 来转义反斜杠和百分比环境变量值中的符号.最后的问题:某些版本的 sed 具有(或曾经)有限的脚本大小容量 - 旧版本的 HP-UX 有大约 100 的限制.我不确定这是否仍然是问题,但就在 5 年前.

Note that if the value of an environment variable contains a slash in your version, you'd run into problems using the slash as the field separator in the s/// notation. I used the '%' since relatively few environment variables use that - but there are some found on some machines that do contain '%' characters and so a complete solution is trickier. You also need to worry about backslashes in the value. You probably have to use something like '$(eval echo "$$var" | sed 's/[\%]/\&/g')' to escape the backslashes and percent symbols in the value of the environment variable. Final wrinkle: some versions of sed have (or had) a limited capacity for the script size - older versions of HP-UX had a limit of about 100. I'm not sure whether that is still an issue, but it was as recently as 5 years ago.

原脚本的简单改编如下:

The simple-minded adaptation of the original script reads:

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 的输出中得到值的事实,所以我们可以这样写:

However, a better solution uses the fact that you already have the values in the output from env, so we can write:

env |
sed 's/[\%]/\&/g;s/([^=]*)=(.*)/s%${1}%2%/' > sed.script
cat test | sed -f sed.script > outputfile

这完全是安全的,因为 shell 从不评估任何不应该被评估的东西——你必须非常小心变量值中的 shell 元字符.我认为,如果 env 的某些输出格式不正确,则此版本可能会遇到任何问题.

This is altogether safer because the shell never evaluates anything that should not be evaluated - you have to be so careful with shell metacharacters in variable values. This version can only possibly run into any trouble if some output from env is malformed, I think.

当心 - 使用 sed 编写 sed 脚本是一项深奥的职业,但却能说明好工具的力量.

Beware - writing sed scripts with sed is an esoteric occupation, but one that illustrates the power of good tools.

所有这些例子都没有清理临时文件.

All these examples are remiss in not cleaning up the temporary file(s).

这篇关于使用 Sed 扩展文件内的环境变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆