替换文本中的环境变量(如果存在)

替换文本中的环境变量(如果存在)

我知道它envsubst会替换输入中声明的环境变量。

$ echo 'Hello $USER' | envsubst
Hello myusername

我想要的是一种替换环境变量(如果环境变量存在)的方法envsusbst(或任何其他命令),使变量字符串保持原样。我得到的是:

$ echo 'Hello $USER $UNDEFINED_VARIABLE' | envsubst
Hello myusername

我想要的是:

$ echo 'Hello $USER $UNDEFINED_VARIABLE' | somecommand
Hello myusername $UNDEFINED_VARIABLE

答案1

如果您传递一个像$USER$PATHto 这样的参数envsubst,那么它只会扩展该参数中引用的那些变量。

因此,一种方法可能是以该格式传递所有当前定义的环境变量。和zsh

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst \$${(kj:$:)parameters[(R)*export*]}
  • $parameters是一个特殊的关联数组,它将变量名称映射到其类型
  • $parameters[(R)*export*]扩展到关联数组中值包含 的所有元素export
  • 使用k参数扩展标志,钥匙而不是返回值
  • j:$:将这些元素连接起来$,并在开头添加一个。

对于其他 shell,您可以随时返回以perl获取该列表:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"

小心泄露你的环境变量名字在 的输出中ps

相反,您也可以在以下位置完成整个操作perl

perl -pe 's{(?|\$\{([_a-zA-Z]\w*)\}|\$([_a-zA-Z]\w*))}{$ENV{$1}//$&}ge'

当心它有相同的局限性就像envsubst那样它不会扩展类似的东西${VAR:-x}并且会扩展$HOME诸如\$HOME$$HOME等 shell 不会扩展的内容。

答案2

您可以使用env查看所有当前定义的环境变量,然后使用该列表仅替换这些变量。 (手册页对此不太清楚,但请参阅这个答案以供说明。)

echo 'Hello $USER $UNKNOWN' | envsubst "$(env | cut -d= -f1 | sed -e 's/^/$/')"

( 的输出env也列出了变量的值,但envsubst也希望看到一个前导$,因此不幸的是,我们不能单独使用cut -d= -f1。您也可以使用单个sed来完成cut工作,请参阅以前的修订版,但我更喜欢清晰度,而cut不是微小的性能增益。)

相关内容