首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用shell脚本替换文件中的标记

使用shell脚本替换文件中的标记
EN

Stack Overflow用户
提问于 2018-06-09 06:00:37
回答 2查看 3.5K关注 0票数 3

我有一个保存令牌变量的文件。当我们切换环境时,我们希望根据我们所处的环境正确地替换这些令牌。

我如何在Linux shell中做到这一点?我在想awk或sed。

示例:

文件中包含以下数据:

代码语言:javascript
复制
DB_HOST=__HOST__
DB_PASSWORD=__PASSWORD__

我想读取这个文件,识别__HOST__,并用环境变量$(HOST)替换它。我们将从两个下划线之间的匹配字符串中获取环境变量名称。

有没有人知道我们是怎么做到的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-09 06:58:31

程序envsubst就是为这个目的而设计的,但是它希望使用标准外壳格式来替换环境中的字符串:

代码语言:javascript
复制
# 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语法:

代码语言:javascript
复制
$ cat myfile.txt
DB_HOST=__HOST__
DB_PASSWORD=__PASSWORD__

$ sed -E 's/__(([^_]|_[^_])*)__/${\1}/g' myfile.txt |envsubst

或者,如果您使用Python,则有一个非常简单的解决方案:

代码语言:javascript
复制
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()))

示例:

代码语言:javascript
复制
$ export HOST=myhost PASSWORD=secret 
$ python3 subst.py < myfile.txt
DB_HOST=myhost
DB_PASSWORD=secret

这个解决方案的关键是,Python (不幸的是,只有少数其他语言)允许模式替换的替换参数是一个函数,然后在每次后续匹配时调用该函数以生成替换文本。这使得在Python中编写这样的函数比在awk中更容易,例如,在awk中替换文本是固定的。

票数 8
EN

Stack Overflow用户

发布于 2018-06-09 06:14:12

这就是m4的用途:

代码语言:javascript
复制
$ 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

如果你想为所有的环境变量自动定义宏,这当然是可能的,如果有点不确定的话:

代码语言:javascript
复制
$ 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"

这不一定是最简单的方法,但它具有高度的灵活性和可扩展性,支持条件语句、宏函数等。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50768918

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档