如何用jq选择和合并对象数据?

时间:2016-09-01 11:10:18

标签: json shell command-line jq

使用jq玩了几个小时后,我需要你帮助选择和合并对象。

我有这种JSON:

{
    "cluster-1": {
        "vhosts": {
            "vhost_aaa": {
                "postgresql": {
                    "bdd1": {
                        "db_aaa": {
                            "user_aaa": {
                                "password": "xxx"
                            }
                        }
                    },
                    "bdd2": {
                        "db_aaa": {
                            "user_aaa": {
                                "password": "xxx"
                            }
                        }
                    }
                }
            }
        }
    },
    "cluster-2": {
        "vhosts": {
            "vhost_bbb": {
                "postgresql": {
                    "bdd1": {
                        "db_bbb": {
                            "user_bbb": {
                                "password": "xxx"
                            },
                            "user_bbb_ro": {
                                "password": "xxx"
                            }
                        }
                    }
                }
            },
            "vhost_ccc": {
                "postgresql": {
                    "bdd1": {
                        "db_ccc": {
                            "user_ccc": {
                                "password": "xxx"
                            }
                        }
                    }
                }
            }
        }
    }
}

这是一个很深的JSON告诉我,在 cluster-x 上有vhosts( vhosts_xxx )可能会使用某种数据库(这里是 postgresql )由服务器(此处为 bdd1 bdd2 )托管,其中包含我想要创建的数据库( db_xxx )具有凭据详细信息的用户( user_xxx )。哇!

我的目标是选择部分数据来执行特定操作,因此对于数据库服务器,我希望所有操作都在同一服务器上执行,因此这是我尝试使用jq生成的内容:

"bdd1": {
    "db_aaa": {
        "user_aaa": {
            "password": "xxx"
        }
    },
    "db_bbb": {
        "user_bbb": {
            "password": "xxx"
        },
        "user_bbb_ro": {
            "password": "xxx"
        }
    },
    "db_ccc": {
        "user_ccc": {
            "password": "xxx"
        }
    }
},
"bdd2": {
    "db_aaa": {
        "user_aaa": {
            "password": "xxx"
        }
    }
}

使用此过滤器(..|.vhosts?|..|.postgresql?)|objects,我可以隔离我需要的数据。

{
  "bdd1": {
    "db_aaa": {
      "user_aaa": {
        "password": "xxx"
      }
    }
  },
  "bdd2": {
    "db_aaa": {
      "user_aaa": {
        "password": "xxx"
      }
    }
  }
}
{
  "bdd1": {
    "db_bbb": {
      "user_bbb": {
        "password": "xxx"
      },
      "user_bbb_ro": {
        "password": "xxx"
      }
    }
  }
}
{
  "bdd1": {
    "db_ccc": {
      "user_ccc": {
        "password": "xxx"
      }
    }
  }
}

下一步是合并按 bddx 分组的所有这些数据。 欢迎任何帮助或建议:)

3 个答案:

答案 0 :(得分:0)

您可以使用to_entries将对象转换为属性/值的键/值对数组。然后,您可以将这些对分组以构建结果。

[..|.vhosts?|..|.postgresql?|objects|to_entries[]]
    | reduce group_by(.key)[] as $g ({};
        .[$g[0].key] = [$g[].value]
    )

这产生以下结果:

{
  "bdd1": [
    {
      "db_aaa": {
        "user_aaa": { "password": "xxx" }
      }
    },
    {
      "db_ccc": {
        "user_ccc": { "password": "xxx" }
      }
    },
    {
      "db_bbb": {
        "user_bbb": { "password": "xxx" },
        "user_bbb_ro": { "password": "xxx" }
      }
    }
  ],
  "bdd2": [
    {
      "db_aaa": {
        "user_aaa": { "password": "xxx" }
      }
    }
  ]
}

答案 1 :(得分:0)

避免使用..可能更安全(即更强大)。如果数据按照您的指示进行结构化,则以下过滤器适合执行任务的“选择”部分:

to_entries[] | .value.vhosts
| to_entries[] | .value.postgresql // empty

然后你可以按照Jeff建议的那样使用它:

[to_entries[] | .value.vhosts | to_entries[] | .value.postgresql // empty | to_entries[]] | group_by(.key) | reduce .[] as $g ({}; .[$g[0].key] = [$g[].value] )

答案 2 :(得分:0)

以下是reduce Sylvain使用* object multiplication过滤的另一种解决方案

reduce ((..|.vhosts?|..|.postgresql?)|objects) as $i({}; . *= $i)

使用它生成的样本数据

{
  "bdd1": {
    "db_aaa": {
      "user_aaa": {
        "password": "xxx"
      }
    },
    "db_bbb": {
      "user_bbb": {
        "password": "xxx"
      },
      "user_bbb_ro": {
        "password": "xxx"
      }
    },
    "db_ccc": {
      "user_ccc": {
        "password": "xxx"
      }
    }
  },
  "bdd2": {
    "db_aaa": {
      "user_aaa": {
        "password": "xxx"
      }
    }
  }
}