Замена переменных среды в файле свойств

В Linux, скажем, у меня есть следующий файл (например, conf.properties):

HOST_URL=http://$HOSTNAME
STD_CONFIG=http://$HOSTNAME/config
USER_CONFIG=http://$HOSTNAME/config/$unconfigured

Я хочу создать другой файл со всеми замененными переменными среды... например. скажем, переменная окружения $HOSTNAME - это "myhost", а $unconfigured не установлен, script должен произвести следующий вывод:

HOST_URL=http://myhost
STD_CONFIG=http://myhost/config
USER_CONFIG=http://myhost/config/

Я думал, что это можно сделать в простой однострочной линии с какой-то магией sed/awk, но я не эксперт, и мои поиски были вены, поэтому оцените любую помощь.

Edit:

Я должен упомянуть, что файл действительно может быть любым текстовым файлом формата, например xml. Я просто хочу заменить все, что похоже на переменную env, с тем, что в настоящее время установлено в среде.

Ответ 1

sed 's/$HOSTNAME/myhost/g;s/$unconfigured//g' yourfile.txt > another_file.txt

обновление:

Исходя из обновлений вашего вопроса, это не будет хорошим решением.

update2:

Это основано на ответе на соответствующий вопрос. Я взломал его (я незнаком с perl), чтобы удалить undefined vars.

perl -p -e 's/\$\{([^}]+)\}/defined $ENV{$1} ? $ENV{$1} : $&/eg; s/\$\{([^}]+)\}//eg' yourfile.txt

Должен работать для любого входного текстового файла, однако вам нужно будет определить vars, используя формат ${...}, который упрощает сопоставление строк.

(rant относительно зла eval переместился в отдельный пост, чтобы не путать читателей)

Ответ 2

Это для envsubst.

echo 'Hello $USER'
Hello $USER
echo 'Hello $USER' | envsubst
Hello malvineous

Возможно, вы, скорее всего, будете использовать его, как это:

envsubst < input.txt > output.txt

envsubst кажется частью GNU gettext.

Ответ 3

Я бы сделал это вот так:

# Set the $HOSTNAME and other variables
# Now evaluate the properties file as a shell script.
. config.properties
# Write the values
cat >somefile <<EOF
HOST_URL=$HOST_URL
STD_CONFIG=$STD_CONFIG
USER_CONFIG=$USER_CONFIG
EOF

Изменить: или эта очень неприятная вещь (я уверен, что там лучший способ)

for name in HOST_URL STD_CONFIG USER_CONFIG
    echo "$name=$(eval echo `echo '$'$name`)" >>somefile
end

Ответ 4

"eval is evil"

Это не ответ, а предупреждение в ответ на использование eval для этой задачи. Вы действительно действительно не хотите этого делать.

Иллюстрация 1: файл вредоносного шаблона:

HOST_URL=http://$HOSTNAME
STD_CONFIG=http://$HOSTNAME/config
USER_CONFIG=http://$HOSTNAME/config/$unconfigured
&& cat /etc/redhat-release

Не подозревающий пользователь:

[[email protected]]$ cat somefile | while read line; do echo $(eval echo `echo $line`); done
HOST_URL=http://xyz
STD_CONFIG=http://xyz/config
USER_CONFIG=http://xyz/config/
Red Hat Enterprise Linux WS release 4 (Nahant Update 9)

Обратите внимание на последнюю строку!

Теперь представьте возможности....

Ответ 5

Благодаря @DarkDust я придумал следующее:

cat somefile | while read line; do echo $(eval echo `echo $line`); done > somefile.replaced

Ответ 6

Я использовал этот oneliner для замены переменных стиля ${VARIABLE} в файле:

TARGET_FILE=/etc/apache2/apache2.conf; for VARNAME in $(grep -P -o -e '\$\{\S+\}' ${TARGET_FILE} | sed -e 's|^\${||g' -e 's|}$||g' | sort -u); do sed -i "s|\${$(echo $VARNAME)}|${!VARNAME}|g" ${TARGET_FILE}; done

Я уверен, что кто-то может сделать это в 1/3-й части, используя awk... чувствовать себя оспоренным!;)

Ответ 7

Здесь короткий однострочный шрифт, который использует форматирование фигурных скобок python, чтобы безопасно выполнять магию:

contents=\"\"\"`cat $file`\"\"\"; python -c "import os;print $contents.format(**os.environ)"
  • избегает зла ​​eval
  • позволяет выводить фигурные скобки: используйте {{ вместо {
  • Не нужно явно указывать vars при вызове script

Например, данный файл свойств settings.properties:

# my properties file
someVar = {MY_ENV_VAR}
curlyBraceVar = has {{curly braces}}

Затем заменим:

$ export MY_ENV_VAR="hello"
$ file=settings.properties 
$ contents=\"\"\"`cat $file`\"\"\"; python  -c "import os;print $contents.format(**os.environ)"
# my properties file
someVar = hello
curlyBraceVar = has {curly braces}

A script находится здесь: https://raw.githubusercontent.com/aneilbaboo/machome/master/bin/substenv