문자열 보간은 bash에서 따옴표를 유지합니다.

문자열 보간은 bash에서 따옴표를 유지합니다.

사용자 환경 변수의 일부 값을 대체하는 json의 본문을 포맷해야 합니다. bash 스크립트에서 json 문자열을 적절하게 대체하는 방법을 shopt 또는 다른 방법을 통해 찾으십시오. 그러나 큰따옴표를 유효한 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 문자열을 미리 모르고 구조나 이름을 미리 모르기 때문에 수동으로 형식을 다시 지정할 수 없다는 것입니다. 내가 풀 필요는 없어이것콘크리트 케이스 - 이것은 장난감의 예입니다. 나는 예제로 표현된 임의의 문자열에 대한 일반적인 솔루션을 공식화하려고 합니다. 키, 값 또는 둘 다 환경 변수일 수 있습니다. 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"

나는 종종 복잡한 json 객체를 처리하기 위해 heredocs를 사용합니다.

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"}

그러나 a) 일치하는 환경 변수뿐만 아니라 모든 환경 변수를 확장하고 env_*b) 유효한 JSON을 만들기 위해 아무 것도 인용하지 않습니다. 예를 들어 , 손상된 참조가 env_var1='double"quote'있습니다 .{"key1": "double"quote", ...

env_*첫 번째 문제를 해결하려면 Bash에서 비슷한 작업을 수행하여 일치하는 변수 이름 목록이 포함된 문자열을 얻을 수 있습니다 envsubst.

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

(문제는 부팅 $플래그가 필요하다는 것입니다.)

envsubst두 번째 변수의 경우 변수를 로 또는 에서 전달하기 전에 변수를 전처리 해야 합니다 jq.

다음과 같은 작업은 --arglike라는 이름의 모든 변수에 대한 옵션을 생성하고 입력 문자열의 모든 항목을 변경하여 변수로 인식되도록 합니다(관련되지 않은 일치 문자열도 변경된다는 점에 유의하세요).jqenv_*"${foo}"$foojq

#!/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"'"}'

아마도 가장 읽기 쉬운 첫 번째 항목을 추천하고 싶습니다.

관련 정보