简体   繁体   中英

How can I process variable substitutions in bash?

So I have some files that contain placeholder values like @USER@ or @SHELL@ (all-caps variable names, enclosed in @'s, representing environment variable names). What I want to do is replace those placeholders with actual values of the environment varables they reference.

In the past when I've seen this sort of thing done, the specific variables are usually hard-coded, eg:

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

But that won't work for my current use-case as I want to more flexibly support arbitrary substitutions. I wrote this code in python which does exactly what I want:

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))

But I'd prefer not to use python if I can help it. Surely there's a way to do this with a perl or sed one-liner?

perl -pe 's/\\@(\\w+)\\@/$ENV{$1}/g' would be one way to do the job.

If you want to throw an error if a variable mentioned in the file doesn't exist in the environment, you could use

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

Ah, it's been too long since I've played with perl, this does exactly what I want:

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

And then in a Makefile you need to escape the dollar signs:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM