интерполяция строк с сохранением кавычек в bash

интерполяция строк с сохранением кавычек в bash

Мне нужно отформатировать тело json, которое получает некоторые значения, заменяемые из переменных среды пользователя. Пытаюсь найти способ через shopt или что-то в этом роде, чтобы строка json была правильно замещена в скрипте bash, но сохраняла/возвращала двойные кавычки, чтобы быть допустимым json. Пробовал предварительную обработку кавычек и двойные кавычки.

Пример:

$ export env_var1=val1
$ export env_var2=val2
$ export args='{"key1": "${env_var1}", "key2": "${env_var2}"}'
$ echo $args #original input
$ eval echo $args #bad output- variables interpolated but quotes lost
Expected output= {"key1": "val1", "key2": "val2"}

Редактировать: Мое ограничение здесь в том, что я не знаю произвольную строку json заранее и не могу переформатировать ее вручную, потому что структура или имена мне заранее не известны. Мне не нужно решатьэтотконкретный случай - это игрушечный пример. Я пытаюсь сформулировать общее решение для произвольной строки, представителем которой является пример. Ключи, значения или и то, и другое могут быть переменными env. JSON может быть произвольно вложенным и большим.

решение1

Вы могли бы избежать кавычек:

{\"key1\": \""$env_var1"\", "key2": \""$env_var2"\"}

Вы можете использовать jq:

jq -n --arg one "$env_var1" --arg two "$env_var2" '{key1: $one, key2: $two}'

ИлиДжо:

jo key1="$env_var1" key2="$env_var2"

Я часто использую heredocs для сложных объектов JSON:

read -rd '' json <<EOF
{
    key1: "$env_var1",
    key2: "$env_var2"
}
EOF
echo "$json"

решение2

В принципе, с этими точными переменными вы могли бы использовать envsubst:

$ export env_var1=val1
$ export env_var2=val2
$ export args='{"key1": "${env_var1}", "key2": "${env_var2}"}'
$ echo "$args" | envsubst
{"key1": "val1", "key2": "val2"}

Но обратите внимание, что это а) расширит любые переменные среды, а не только те, которые соответствуют env_*, и б) не будет заключать в кавычки никакое содержимое, чтобы сделать его допустимым JSON. Например, с env_var1='double"quote', вы получите {"key1": "double"quote", ..., с нарушенными кавычками.

Чтобы исправить первую проблему, можно сделать что-то вроде этого в Bash, чтобы получить строку, содержащую список имен переменных, env_*соответствующих envsubst:

$ echo "$args" | envsubst "$(printf '$%s ' "${!env_@}")"
{"key1": "val1", "key2": "val2"}

(проблема в том, что для этого требуются ведущие $знаки.)

Во втором случае вам придется предварительно обработать переменные перед передачей их в envsubstили передать их через jq.

Что-то вроде этого сгенерирует --argпараметры для jqвсех переменных с именами типа env_*, и изменит любую "${foo}"из входной строки на , чтобы $fooраспознавать jqих как переменные (обратите внимание, что это также изменит любые несвязанные совпадающие строки):

#!/bin/bash

args=(); 
for varname in "${!env_@}"; do
    args+=(--arg "$varname" "${!varname}");
done;
jq -n -c -M "${args[@]}" "$(sed -E -e 's/"\$\{([a-zA-Z0-9_]+)\}"/$\1/g' <<< "$1")"

Бежать с:

$ export env_var1='double"quote' env_var2=foobar
$ bash jsonexpand.sh '{"key1": "${env_var1}", "key2": "${env_var2}"}'
{"key1":"double\"quote","key2":"foobar"}

решение3

Вам нужно заключить выражение в кавычки, чтобы оболочка не анализировала его. В тривиальном случае,

echo '{"key1": "var1", "key2": "var2"}'

В вашем случае, когда вам нужна интерполяция переменных, любой из этих вариантов может подойти.

printf '{"key1": "%s", "key2": "%s"}\n' "$env_var1" "$env_var2"
echo "{\"key1\": \"$env_var1\", \"key2\": \"$env_var2\"}"
echo '{"key1": "'"$env_var1"', "key2": "'"$env_var2"'"}'

Я бы, пожалуй, порекомендовал первую из них как наиболее читаемую.

Связанный контент