我有一个保存令牌变量的文件。当我们切换环境时,我们希望根据我们所处的环境正确地替换这些令牌。
我如何在Linux shell中做到这一点?我在想awk或sed。
示例:
文件中包含以下数据:
DB_HOST=__HOST__
DB_PASSWORD=__PASSWORD__
我想读取这个文件,识别__HOST__
,并用环境变量$(HOST)
替换它。我们将从两个下划线之间的匹配字符串中获取环境变量名称。
有没有人知道我们是怎么做到的?
发布于 2018-06-09 06:58:31
程序envsubst
就是为这个目的而设计的,但是它希望使用标准外壳格式来替换环境中的字符串:
# Here-doc delimiter quoted to avoid having the shell do the substitutions
$ HOST=myhost PASSWORD=secret envsubst <<"EOF"
DB_HOST=$HOST
DB_PASSWORD=${PASSWORD}
EOF
DB_HOST=myhost
DB_PASSWORD=secret
envsubst
是Gnu gettext的一部分,并且广泛可用。如果您确实需要使用__...__
语法,那么可以通过管道将其更改为envsubst
语法:
$ cat myfile.txt
DB_HOST=__HOST__
DB_PASSWORD=__PASSWORD__
$ sed -E 's/__(([^_]|_[^_])*)__/${\1}/g' myfile.txt |envsubst
或者,如果您使用Python,则有一个非常简单的解决方案:
from sys import stdin
from os import getenv
import re
pattern = re.compile(r"__(\w*)__")
def replacer(m):
val = getenv(m[1])
if val is None:
# No such environment
# Perhaps produce a warning, or an error
# Here we just pass through the string unaltered
return m[0]
return val
print(pattern.sub(replacer, stdin.read()))
示例:
$ export HOST=myhost PASSWORD=secret
$ python3 subst.py < myfile.txt
DB_HOST=myhost
DB_PASSWORD=secret
这个解决方案的关键是,Python (不幸的是,只有少数其他语言)允许模式替换的替换参数是一个函数,然后在每次后续匹配时调用该函数以生成替换文本。这使得在Python中编写这样的函数比在awk中更容易,例如,在awk中替换文本是固定的。
发布于 2018-06-09 06:14:12
这就是m4
的用途:
$ export HOST=myhost PASSWORD=mypassword
$ cat myfile
DB_HOST=__HOST__
DB_PASSWORD=__PASSWORD__
$ m4 -D __HOST__="$HOST" -D __PASSWORD__="$PASSWORD" myfile
DB_HOST=myhost
DB_PASSWORD=mypassword
如果你想为所有的环境变量自动定义宏,这当然是可能的,如果有点不确定的话:
$ cat mymacros.m4
esyscmd(`env | sed -ne "s/^\([A-Z_]*\)=\(.*\)/define(__\1__, \`\2')/p" | tr -d "\n"')
$ cat myfile2
include(`mymacros.m4')
DB_HOST=__HOST__
DB_PASSWORD=__PASSWORD__
And other arbitrary text containing things like "My editor is __EDITOR__"
$ m4 myfile2
DB_HOST=myhost
DB_PASSWORD=mypassword
And other arbitrary text containing things like "My editor is vim"
这不一定是最简单的方法,但它具有高度的灵活性和可扩展性,支持条件语句、宏函数等。
https://stackoverflow.com/questions/50768918
复制相似问题