Bash
在bash中保留引號的字元串插值
我必須格式化從使用者環境變數中替換一些值的 json 正文。試圖通過 shopt 或其他方式找到一種方法,以便在 bash 腳本中正確替換 json 字元串,但保留/放回雙引號以成為有效的 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 可以任意嵌套並且很大。
原則上,使用這些確切的變數,您可以使用
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", ...
, 引用中斷。要解決第一個問題,您可以在 Bash 中執行類似的操作,以獲取包含與以下內容匹配的變數名稱列表的
env_*
字元串envsubst
:$ echo "$args" | envsubst "$(printf '$%s ' "${!env_@}")" {"key1": "val1", "key2": "val2"}
(問題是它需要前導
$
標誌。)其次,您必須在將變數傳遞給之前對變數進行預處理
envsubst
,或者將它們傳遞給jq
.像這樣的東西會為所有名為 like 的變數生成
--arg
選項,並將輸入字元串中的any 更改為以便將它們辨識為變數(請注意,它也會更改任何不相關的匹配字元串):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"}