Bash

在bash中保留引號的字元串插值

  • June 2, 2021

我必須格式化從使用者環境變數中替換一些值的 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"}

引用自:https://unix.stackexchange.com/questions/652503