我有一个包含令牌变量的文件。当我们切换环境时,我们想要为我们所处的环境正确替换这些令牌。
如何在Linux shell中执行此操作?我在想awk或sed。
示例:
文件包含以下数据:
DB_HOST=__HOST__
DB_PASSWORD=__PASSWORD__
我想阅读此文件,识别__HOST__
并将其替换为环境变量$(HOST)
。我们将从两个下划线之间的匹配字符串中获取环境变量名称。
有没有人知道我们该如何做到这一点?
答案 0 :(得分:3)
程序envsubst
是为了这个目的而设计的,但它希望使用标准的shell格式来从环境中替换字符串:
# 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的一部分,并且可以广泛使用。如果您确实需要使用__...__
语法,则可以通过sed管道将其更改为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中更容易,例如,替换文本是固定的。
答案 1 :(得分:1)
这是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"
这不一定是最简单的方法,但它非常灵活和可扩展,支持条件语句,宏函数等。
答案 2 :(得分:0)
这就是您想要的:
while IFS= read -r line || [[ -n "$line" ]]; do
from=$(echo $line | cut -d '=' -f 1 )
to=$(echo $line | cut -d '=' -f 2 )
sedString=${sedString}" s/__${from}__/${to}/g;"
done < tokenFile.txt
sed "${sedString}" old.txt >> new.txt
它将用tokenFile.txt构建一个包含所有所需替换项的字符串,然后使用一个sed命令一次将所有替换项替换为您指定的任何文件。 tokenFile.txt具有“旧=新”对。 old.txt是带有令牌的文件。 new.txt是您输出的地方。
例如,运行脚本后,您将得到:
$ cat tokenFile.txt
DB_HOST=127.0.0.1
$ cat old.txt
dbconnect __DB_HOST__
$ cat new.txt
dbconnect 127.0.0.1