【问题标题】:How can I process variable substitutions in bash?如何在 bash 中处理变量替换?
【发布时间】:2015-11-25 00:19:24
【问题描述】:

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

过去我看到这种事情做的时候,具体的变量通常是硬编码的,例如:

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 单线器来做到这一点?

【问题讨论】:

    标签: python bash perl sed environment-variables


    【解决方案1】:

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

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

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

    envsubst = perl -pe 's/@([A-Z_]+)@/$$ENV{$$1} or die "$$1 undefined"/eg'
    
    install:
        $(envsubst) <infile1 >outfile1
        $(envsubst) <infile2 >outfile2
    

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 如果变量未定义,有没有办法让 perl 抱怨?如果我的环境变量设置错误,比在我的文件中静默留空白要好。
      • 来自die 的失败状态应该足以让make 退出。
      • 这也有效,而且更短:perl -pe 's/@([A-Z_]+)@/$ENV{$1} or die "$1 undefined"/eg'(我意识到它们在语义上并不完全相同,但我的用例不需要“变量设置为空值”,所以没关系)跨度>
      • @Robru 值 0 的变量怎么样?当心。我会在工具中使用我的版本,“更短”并不是那么重要。
      • 啊,string "0" 的虚伪性太可怕了,我习惯了只有空字符串为假的python。至少在我的用例中,我只替换像用户名和路径这样的长字符串,所以对我来说,为空字符串引发错误是一个功能。我预计在任何时候都不需要扩展到“0”。
      猜你喜欢
      • 2015-10-17
      • 2016-12-02
      • 1970-01-01
      • 2017-08-30
      • 2019-02-19
      • 2022-11-11
      • 2018-01-14
      • 1970-01-01
      • 2011-12-02
      相关资源
      最近更新 更多