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"

나는 종종 복잡한 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.

이와 같은 것은 like 라는 이름의 모든 변수 --arg에 대한 옵션을 생성하고 입력 문자열의 모든 항목을 변수로 인식 하도록 변경합니다 (관련되지 않은 일치 문자열도 변경된다는 점에 유의하세요).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"'"}'

나는 아마도 이들 중 첫 번째를 가장 읽기 쉬운 것으로 추천하고 싶습니다.

관련 정보