如何从JSON文件生成列表并过滤缺失EMAIL/JOB_TITLE的对象
问题描述
我尝试从JSON文件提取数据,但无法过滤掉缺少EMAIL或JOB_TITLE任一值的对象。
示例JSON
[{"primary": "JOHN DOE", "attributes": [{"type": "double", "name":"BUILDING_NUMBER", "value": "123"}, {"type": "double", "name": "FLOOR", "value": 10}, {"type": "string", "name": "EMAIL", "value":"john.doe@contoso.com"}, {"type": "string", "name": "JOB_TITLE", "value": "SALESMAN"} ], "aliases": [{"alias": "joao.doe@contoso.com"}]},{"primary": "LORRAINE DOE", "attributes": [{"type": "double", "name": "BUILDING_NUMBER", "value": 456}, {"type": "double", "name": "FLOOR", "value": 10}, {"type": "string", "name": "STATUS", "value": "Unavaliable"}, {"type": "string", "name": "EMAIL", "value": "lorraine.doe@contoso.com"}, {"type": "string", "name": "JOB_TITLE", "value": "SECRETARY"} ], "aliases": [{"alias": "lorris.doe@contoso.com"}, {"alias": "lorris2.doe@contoso.com"}]},{"primary": "JACK DOE", "attributes": [{"type": "double", "name": "BUILDING_NUMBER", "value": "123"}, {"type": "double", "name": "FLOOR", "value": 10}, {"type": "string", "name":"JOB_TITLE", "value": "OWNER"}], "aliases": [{"alias":"jack.doe@contoso.com"},{"alias": "jackson.doe@contoso.com"}]}, {"primary": "NOAH DOE", "attributes": [{"type": "double", "name": "BUILDING_NUMBER", "value": "123"}, {"type": "double", "name": "FLOOR", "value": 10}, {"type": "string", "name": "EMAIL", "value": "noah.doe@contoso.com"}], "aliases": [{"alias": "noah.doe95@contoso.com"}]}]
期望输出
"john.doe@contoso.com": "SALESMAN", "lorraine.doe@contoso.com": "SECRETARY"
我使用的代码
echo '[{"primary": "JOHN DOE", "attributes": [{"type": "double", "name":"BUILDING_NUMBER", "value": "123"}, {"type": "double", "name": "FLOOR", "value": 10}, {"type": "string", "name": "EMAIL", "value":"john.doe@contoso.com"}, {"type": "string", "name": "JOB_TITLE", "value": "SALESMAN"} ], "aliases": [{"alias": "joao.doe@contoso.com"}]},{"primary": "LORRAINE DOE", "attributes": [{"type": "double", "name": "BUILDING_NUMBER", "value": 456}, {"type": "double", "name": "FLOOR", "value": 10}, {"type": "string", "name": "STATUS", "value": "Unavaliable"}, {"type": "string", "name": "EMAIL", "value": "lorraine.doe@contoso.com"}, {"type": "string", "name": "JOB_TITLE", "value": "SECRETARY"} ], "aliases": [{"alias": "lorris.doe@contoso.com"}, {"alias": "lorris2.doe@contoso.com"}]},{"primary": "JACK DOE", "attributes": [{"type": "double", "name": "BUILDING_NUMBER", "value": "123"}, {"type": "double", "name": "FLOOR", "value": 10}, {"type": "string", "name":"JOB_TITLE", "value": "OWNER"}], "aliases": [{"alias":"jack.doe@contoso.com"},{"alias": "jackson.doe@contoso.com"}]}, {"primary": "NOAH DOE", "attributes": [{"type": "double", "name": "BUILDING_NUMBER", "value": "123"}, {"type": "double", "name": "FLOOR", "value": 10}, {"type": "string", "name": "EMAIL", "value": "noah.doe@contoso.com"}], "aliases": [{"alias": "noah.doe95@contoso.com"}]}]' | jq '.[].attributes[]|select(.name|contains("JOB_TITLE"), contains ("EMAIL"))' | jq .value | sed 'N;s/\n/:/' | sed 's/$/,/'
解决方案
你的问题出在没有先过滤掉同时缺少EMAIL和JOB_TITLE的对象,而是直接提取所有含EMAIL或JOB_TITLE的属性,导致单个对象仅含其中一个属性时也被提取,最终拼接出错。
可以用jq一步完成过滤和格式输出,无需额外sed处理,更简洁可靠:
echo '[{"primary": "JOHN DOE", "attributes": [{"type": "double", "name":"BUILDING_NUMBER", "value": "123"}, {"type": "double", "name": "FLOOR", "value": 10}, {"type": "string", "name": "EMAIL", "value":"john.doe@contoso.com"}, {"type": "string", "name": "JOB_TITLE", "value": "SALESMAN"} ], "aliases": [{"alias": "joao.doe@contoso.com"}]},{"primary": "LORRAINE DOE", "attributes": [{"type": "double", "name": "BUILDING_NUMBER", "value": 456}, {"type": "double", "name": "FLOOR", "value": 10}, {"type": "string", "name": "STATUS", "value": "Unavaliable"}, {"type": "string", "name": "EMAIL", "value": "lorraine.doe@contoso.com"}, {"type": "string", "name": "JOB_TITLE", "value": "SECRETARY"} ], "aliases": [{"alias": "lorris.doe@contoso.com"}, {"alias": "lorris2.doe@contoso.com"}]},{"primary": "JACK DOE", "attributes": [{"type": "double", "name": "BUILDING_NUMBER", "value": "123"}, {"type": "double", "name": "FLOOR", "value": 10}, {"type": "string", "name":"JOB_TITLE", "value": "OWNER"}], "aliases": [{"alias":"jack.doe@contoso.com"},{"alias": "jackson.doe@contoso.com"}]}, {"primary": "NOAH DOE", "attributes": [{"type": "double", "name": "BUILDING_NUMBER", "value": "123"}, {"type": "double", "name": "FLOOR", "value": 10}, {"type": "string", "name": "EMAIL", "value": "noah.doe@contoso.com"}], "aliases": [{"alias": "noah.doe95@contoso.com"}]}]' | jq -r ' .[] | select(.attributes | any(.name == "EMAIL") and any(.name == "JOB_TITLE")) | (.attributes | from_entries) | "\"\(.EMAIL)\": \"\(.JOB_TITLE)\"," ' | sed '$s/,$//'
代码解释:
.[]:遍历数组中的每个对象select(.attributes | any(.name == "EMAIL") and any(.name == "JOB_TITLE")):只保留同时包含EMAIL和JOB_TITLE属性的对象(.attributes | from_entries):把attributes数组转换为键值对对象,方便直接调用.EMAIL和.JOB_TITLE"\(.EMAIL)\": \"\(.JOB_TITLE)\",":按期望格式输出字符串sed '$s/,$//':去掉最后一行的逗号,让格式更规范
运行后即可得到目标输出:
"john.doe@contoso.com": "SALESMAN", "lorraine.doe@contoso.com": "SECRETARY"
内容的提问来源于stack exchange,提问作者Robson
相关产品推荐
相关产品推荐

