Как я могу обрабатывать подстановки переменных в bash?

116
7

Поэтому у меня есть некоторые файлы, содержащие значения заполнителя, такие как @USER@ или @SHELL@ (имена переменных all-caps, заключенные в @, представляющие имена переменных среды). Я хочу, чтобы заменить эти заполнители фактическими значениями переменных, которые они ссылаются.

Раньше, когда я видел подобное, конкретные переменные обычно жестко закодированы, например:

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 one-liner?

спросил(а) 2021-01-25T14:06:35+03:00 4 месяца, 3 недели назад
1
Решение
88

perl -pe 's/\@(\w+)\@/$ENV{$1}/g' будет одним из способов выполнения задания.

Если вы хотите выбросить ошибку, если переменная, указанная в файле, не существует в среде, вы можете использовать

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

ответил(а) 2021-01-25T14:06:35+03:00 4 месяца, 3 недели назад
45

Ах, это было слишком долго, так как я играл с 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

ответил(а) 2021-01-25T14:06:35+03:00 4 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема