如何使用jq过滤嵌套JSON数据以提取指定字段?
使用jq提取嵌套JSON指定字段的解决方案
示例JSON结构参考
假设你的原始JSON核心层级如下(冗余字段已省略):
{ "matchId": "12345", "timestamp": 1690000000, "clubs": { "club_1": { "passa": 100, "passc": 85, "ppg": 2, "ppo": 1, "shots": 12, "toa": 90, "details": { "name": "Team A", "clubId": "club_a" } }, "club_2": { "passa": 90, "passc": 78, "ppg": 1, "ppo": 2, "shots": 15, "toa": 90, "details": { "name": "Team B", "clubId": "club_b" } } }, "players": { "club_1": { "player_1": { "goals": 2, "assists": 1, "minutes": 90 }, "player_2": { "goals": 0, "assists": 2, "minutes": 80 } }, "club_2": { "player_3": { "goals": 1, "assists": 0, "minutes": 90 } } } }
固定规则的jq命令
如果指定玩家和字段是固定的(比如只保留player_1、player_3的goals、assists、minutes),用以下命令:
{ matchId, timestamp, clubs: .clubs | with_entries( .value |= { passa, passc, ppg, ppo, shots, toa, details: .details | {name, clubId} } ), players: .players | with_entries( .value |= with_entries( select(.key == "player_1" or .key == "player_3") | .value |= {goals, assists, minutes} ) | del(keys[] | select(.[0] | length == 0)) ) }
灵活参数版jq命令
如果需要动态指定玩家和统计字段,用--argjson传参更便捷:
# 替换成你的目标玩家列表和统计字段 jq --argjson target_players '["player_1", "player_3"]' \ --argjson target_stats '["goals", "assists", "minutes"]' \ ' { matchId, timestamp, clubs: .clubs | with_entries( .value |= { passa, passc, ppg, ppo, shots, toa, details: .details | {name, clubId} } ), players: .players | with_entries( .value |= ( with_entries(select(.key | IN($target_players[]))) | map_values(.[$target_stats[]]) ) | del(keys[] | select(.[0] | length == 0)) ) }' your_input.json
关键逻辑说明
- 顶层字段提取:
{matchId, timestamp}是jq简写语法,直接保留指定顶层字段。 - Clubs动态键处理:
with_entries遍历每个俱乐部的动态键值对- 对每个俱乐部对象,仅保留指定统计字段,同时从
details中提取name和clubId
- Players筛选与提取:
- 外层
with_entries遍历每个俱乐部的玩家集合 - 内层
with_entries结合select筛选出指定玩家 map_values(.[$target_stats[]])提取指定统计字段- 最后的
del(...)用于删除没有匹配到指定玩家的空俱乐部条目(可选)
- 外层
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

