如何在Bash变量中使用jq读取带连字符的JSON键值
解析含连字符的JSON键名问题
我需要解析键名包含连字符的JSON属性值,操作步骤如下:
- 通过子shell命令将JSON内容读取到变量:
srcJson=$(someshellcommand) - 将变量传入jq读取属性值(后续会用sed处理,此处无关):
value=$(echo $srcJson | jq .root.parent.$srcKey | sed -e 's/\\\"/\"/g' -e 's/^.//g' -e 's/.$//g')
在Mac的Bash脚本中运行时,$srcKey不含连字符时正常,但包含连字符(比如Part1OfHypenatedKey-Part2OfHypenatedKey)时会报错:
jq: error: Part1OfHypenatedKey/0 is not defined at <top-level> jq: error: Part2OfHypenatedKey/0 is not defined at <top-level>
我试过两种修改方式,但都无效:
- 仅给变量加引号:
value=$(echo $srcJson | jq .root.parent."$srcKey" | sed -e 's/\\\"/\"/g' -e 's/^.//g' -e 's/.$//g') - 给整个jq键路径加引号:
value=$(echo $srcJson | jq ".root.parent.$srcKey" | sed -e 's/\\\"/\"/g' -e 's/^.//g' -e 's/.$//g')
正确解决方法
jq处理含特殊字符(比如连字符)的键名时,需要用引号包裹键名,同时规避Bash与jq的字符串解析冲突,推荐两种可靠方式:
方式1:使用jq的--arg参数传递变量(最优)
通过jq内置的变量传递机制,彻底避免字符串插值问题:
value=$(echo "$srcJson" | jq --arg key "$srcKey" '.root.parent[$key]' | sed -e 's/\\\"/\"/g' -e 's/^.//g' -e 's/.$//g')
--arg key "$srcKey":将Bash变量$srcKey传递给jq,在jq内部用$key引用.root.parent[$key]:通过数组下标语法访问键名,自动兼容含连字符的键
方式2:嵌套引号拼接变量
如果坚持使用字符串插值,需通过单引号+双引号的嵌套,确保jq能识别带引号的键名:
value=$(echo "$srcJson" | jq '.root.parent."'$srcKey'"' | sed -e 's/\\\"/\"/g' -e 's/^.//g' -e 's/.$//g')
另外建议给echo $srcJson中的变量添加双引号:echo "$srcJson",避免JSON内容中的空格或特殊字符被Bash拆分。
内容的提问来源于stack exchange,提问作者Aditya Dara
相关产品推荐
相关产品推荐

