Bash脚本处理含转义序列的JSON时转义错误的原因分析与解决方法
Bash脚本处理含转义序列的JSON时转义错误的原因分析与解决方法
你遇到的这个问题,核心是手动在Bash里处理JSON转义时,没兼顾Bash本身的字符串解析规则和JSON的嵌套转义要求,导致转义层数少了一层,最终让Java后端的JSON解析器报错。
为什么会出现这个错误?
咱们先拆解你原来的脚本逻辑:
- 你用
cat test.json把JSON内容读入变量data,这一步没问题。 - 用
${data//\"/\\\"}把所有双引号替换成转义双引号(\"),这时候原JSON里的"example": "[\"Psychiatry\"]"会被转换成\"example\": \"[\\\"Psychiatry\\\"]\"——这一步其实是对的,已经给Psychiatry前后的双引号加了两层转义。 - 但接下来的
data=$(echo \"$data\" | tr -d ' ')出了问题:echo会自动解析字符串里的转义字符,把\\\"转换成\",相当于直接吃掉了一层转义。最终输出里的example字段就变成了\"[\\"Psychiatry\\"]\",比正确格式少了一层转义,导致后端解析时把P当成了意外字符,触发语法错误。
简单说:Bash的echo命令会解析转义序列,手动替换的转义字符经过echo后被“缩水”了,不符合JSON嵌套字符串的转义要求。
正确的解决方法:用专门的JSON工具处理转义
手动处理JSON转义很容易踩坑,推荐用jq(一款专门处理JSON的命令行工具,几乎所有Linux发行版都能通过包管理器安装)来自动处理转义,它能完美适配JSON的嵌套转义规则。
修正后的完整脚本:
# 用jq读取test.json,自动将JSON转换成符合嵌套要求的字符串形式 data=$(jq -c tostring test.json) # 发起curl请求,注意用双引号包裹整个-d参数,避免Bash错误解析转义 curl -s -H "Accept: application/json" -H "Content-Type: application/json" \ --location --request POST "${HOST}/api/v1/projects" \ --header "Authorization: Bearer $token" \ -d "{\"name\":\"${PROJECT_NAME}\",\"openText\": $data,\"source\": \"API\"}"
为什么这个方法有效?
- jq的
tostring函数会把输入的JSON对象转换成一个标准的JSON字符串,自动处理所有嵌套转义:原example字段里的[\"Psychiatry\"]会被正确转义成[\\\"Psychiatry\\\"],完全符合你需要的格式。 - 全程不需要手动替换转义字符,避免了Bash命令对转义的解析干扰,确保最终传给后端的JSON格式完全正确。
额外提醒
如果你坚持要手动处理(不推荐),需要避免用echo解析转义,可以改用printf "%s" "$data"来输出字符串,这样不会解析转义字符:
data=$(cat test.json) data=${data//\"/\\\"} # 用printf代替echo,保留所有转义字符 data=$(printf "%s" "$data" | tr -d ' ')
但这种方法依然容易在复杂JSON场景下出错,还是推荐用jq这类专业工具更稳妥。
备注:内容来源于stack exchange,提问作者James Taylor
相关产品推荐
相关产品推荐

