如何在Bash脚本或jq中转义JSON标签生成合法JSON
如何在Bash脚本或jq中转义嵌套JSON以生成合法JSON?
我用yq将YAML转成带嵌套结构的JSON后,通过Bash脚本结合jq提取键值对构建新JSON,但嵌套JSON未转义导致生成的JSON无效,需要解决如何转义/字符串化JSON字符以生成合法目标JSON的问题。
原转换后的JSON示例
{ "a" : 1, "b" : 2, "c" : { "id": "9ee ...", "parent": "abc..." } }
当前Bash脚本片段
# Extract the properties from the YAML file json=$(yq -j "$file_name") # Iterate over the properties parameters="" for key in $(echo "${json}" | jq -r 'keys[]'); do # Extract the key and value of the property value=$(echo "${json}" | jq -r ".$key") echo "Adding parameter $key with value $value to SSM" # Add the property to the list of parameters parameters+="{\"Name\": \"$key\", \"Value\": \"$value\", \"Type\": \"String\", \"Overwrite\": true}" done
当前生成的无效JSON示例
[ { "Name": "a", "Value": "1", "Type": "String", "Overwrite": "true" }, { "Name": "b", "Value": "2", "Type": "String", "Overwrite": "true" }, { "Name": "c", "Value": "{ "id": "9ee ...", "parent": "abc..." }", "Type": "String", "Overwrite": "true" } ]
期望生成的合法JSON示例
[ { "Name": "a", "Value": "1", "Type": "String", "Overwrite": "true" }, { "Name": "b", "Value": "2", "Type": "String", "Overwrite": "true" }, { "Name": "c", "Value": "{\r\n \"id\": \"9ee ...\",\r\n \"parent\": \"abc...\"\r\n }", "Type": "String", "Overwrite": "true" } ]
解决方案
方案1:用jq一次性处理(推荐)
完全避免Bash循环拼接JSON的操作,直接用jq完成整个转换逻辑,这是最可靠的方式:
yq -j "$file_name" | jq 'to_entries | map({ Name: .key, Value: (.value | tojson), Type: "String", Overwrite: true })'
说明:
to_entries:将原JSON对象转换为[{key: "a", value: 1}, ...]的数组格式map(...):遍历每个元素,构建目标结构.value | tojson:将值(包括嵌套对象)自动转换为转义后的JSON字符串,处理引号、换行等特殊字符,确保生成的JSON合法
方案2:修改现有Bash脚本
如果必须保留Bash循环的逻辑,需要修改value的提取方式,让jq输出转义后的字符串:
# Extract the properties from the YAML file json=$(yq -j "$file_name") # Iterate over the properties parameters="" first_item=true for key in $(echo "${json}" | jq -r 'keys[]'); do # 提取转义后的value字符串,无需手动加引号 value=$(echo "${json}" | jq ".$key | tojson") echo "Adding parameter $key with value $value to SSM" # 处理数组元素间的逗号 if [ "$first_item" = true ]; then parameters+="{\"Name\": \"$key\", \"Value\": $value, \"Type\": \"String\", \"Overwrite\": true}" first_item=false else parameters+=",{\"Name\": \"$key\", \"Value\": $value, \"Type\": \"String\", \"Overwrite\": true}" fi done # 包裹成数组 final_json="[$parameters]" echo "$final_json"
说明:
jq ".$key | tojson":将值转义为合法的JSON字符串(自带引号,无需手动添加)- 增加了
first_item判断,避免数组开头或末尾出现多余逗号 - 最终将拼接好的字符串包裹在
[]中形成合法数组
内容的提问来源于stack exchange,提问作者VelNaga
相关产品推荐
相关产品推荐

