如何在Bash脚本中使用jq跳过解析失败的JSON键值对
问题:Bash脚本读取JSON导出环境变量时无法跳过解析失败的条目
问题场景
编写Bash脚本读取JSON文件,将其中的键值对导出为环境变量,目前能提取正常的键值对,但无法跳过jq解析失败的条目。
存在解析问题的JSON文件
{ "KEY1":"ABC", "KEY2":"XYZ", "KEY3":"---ABC---\n dskfjlksfj" }
注:KEY3的字符串包含未转义的实际换行,不符合JSON规范,会导致解析失败。
尝试的代码
for pair in $(cat test.json | jq -r -R '. as $line | try fromjson catch $line | to_entries | map("\(.key)=\(.value)") | .[]' ); do echo $pair export $pair done
报错信息
jq: error (at <stdin>:1): string ("{") has no keys jq: error (at <stdin>:2): string (" \"key1...) has no keys
问题原因
你错误使用了jq的-R参数(逐行读取输入为字符串),但你的文件是单个多行JSON对象,逐行读取后,单行内容(比如开头的{)并非完整的JSON对象,执行to_entries时自然报错。此外,原JSON本身因KEY3的格式问题无法被完整解析为合法JSON对象。
解决方案
方案1:修复JSON格式(推荐)
先修正JSON中不符合规范的部分,将KEY3的实际换行改为转义符\n,确保整个JSON合法:
{ "KEY1":"ABC", "KEY2":"XYZ", "KEY3":"---ABC---\ndskfjlksfj" }
然后使用以下脚本提取并导出环境变量:
# 读取合法JSON,提取键值对并导出 while IFS= read -r env_var; do echo "$env_var" export "$env_var" done < <( jq -r ' to_entries[] | "\(.key)=\(.value | tostring)" ' test.json )
方案2:兼容不合法JSON(处理部分解析失败的情况)
如果无法修改原JSON文件,可先预处理修复字符串换行问题,再用jq提取可解析的键值对:
# 预处理修复JSON中的未转义换行,再提取键值对 sed ':a;N;$!ba;s/\("\w*":"[^"]*\)\n/\1\\n/g' test.json | jq -r ' try to_entries[] catch empty | try "\(.key)=\(.value)" catch empty ' | while IFS= read -r env_var; do echo "$env_var" export "$env_var" done
关键优化点
- 去掉
-R参数,让jq直接处理整个JSON对象而非逐行字符串 - 使用
while IFS= read -r替代for循环,避免空格、特殊字符导致的变量拆分问题 - 用
try...catch empty捕获解析失败的条目,自动跳过
内容的提问来源于stack exchange,提问作者Abhishek Chandran
相关产品推荐
相关产品推荐

