如何处理 bash 中的变量替换?

How can I process variable substitutions in bash?

所以我有一些包含占位符值的文件,例如 @USER@@SHELL@(全大写变量名称,包含在 @ 中,代表环境变量名称)。我想要做的是用它们引用的环境变量的实际值替换那些占位符。

以前看到这种事情的时候,具体的变量通常是硬编码的,例如:

sed -e 's/@SOME_VARIABLE@/$SOME_VALUE/' <infile >outfile

但这对我当前的用例不起作用,因为我想更灵活地支持任意替换。我在 python 中编写了这段代码,它完全符合我的要求:

import re
import fileinput

from os import environ
from sys import stdout

pat = re.compile(r'@([A-Z_]+)@')

for line in fileinput.input():
    stdout.write(pat.sub(lambda match: environ[match.group(1)], line))

但如果可以的话,我宁愿不使用 python。肯定有一种方法可以使用 perl 或 sed 单行代码来做到这一点?

啊,太久没玩perl了,这正是我想要的:

perl -pe 's/@([A-Z_]+)@/$ENV{} or die " undefined"/eg' <infile >outfile

然后在 Makefile 中您需要转义美元符号:

envsubst = perl -pe 's/@([A-Z_]+)@/$$ENV{$} or die "$ undefined"/eg'

install:
    $(envsubst) <infile1 >outfile1
    $(envsubst) <infile2 >outfile2

perl -pe 's/\@(\w+)\@/$ENV{}/g' 是完成这项工作的一种方法。

如果你想在环境中不存在文件中提到的变量时抛出错误,你可以使用

perl -pe 's/\@(\w+)\@/die " not found\n" unless exists $ENV{}; $ENV{}/eg'