如何根据另一个JSON文件的键对一个JSON文件进行排序

oipij1gg  于 2023-06-07  发布在  其他
关注(0)|答案(1)|浏览(158)

我有一个翻译管理工具,我上传了一个json文件input.json。接下来,翻译人员执行他/她的翻译工作,结果被导出到包含所有翻译output.json的json文件。input.json和output.json包含相同的键,但不包含相同的值(这些是翻译器添加/修改的翻译)。更重要的是,input.json和output.json中键的顺序完全不同。从功能上讲,这并不重要,但在拉取请求中,input.json是“旧”文件,与output.json的“新”文件进行比较。这会产生很多差异,由于改变了顺序的关键,mking审查繁琐。有没有一种简单的方法可以像对input.json一样对output.json进行排序?
我发现jq可以用来按字母顺序排列input.json,这样我就可以按字母顺序排列output.json了,这就解决了我的问题,但是是否可以使用jq来实际上采取input.json中键的顺序并将其应用于output.json?
下面是input.json的一些演示数据:

{
  "BathroomType": "Type of bathroom",
  "BuildingType": "Type of building",
  "enums": {
    "OrientationGarden": {
      "EAST": "East",
      "SOUTH": "South",
      "NORTH": "North",
      "WEST": "West"
    },
    "TerrainRecentDestination": {
      "EXTRACTION": "extraction",
      "PARK": "park"
    }
  }
}

对于输出:

{
  "BathroomType": "Type of bathroom2",
  "enums": {
    "TerrainRecentDestination": {
      "EXTRACTION": "extraction",
      "PARK": "park"
    },
    "OrientationGarden": {
      "SOUTH": "South",
      "EAST": "East2",
      "NORTH": "North",
      "WEST": "West"
    }
  },
  "BuildingType": "Type of building"
}
ie3xauqp

ie3xauqp1#

使用jq的当前实现(意思是:这个“副作用”没有文档记录,它可能会在没有通知的情况下改变),您可以通过连续构建输出对象来预先确定键的顺序。为此,您将按照使用keys_unsorted读取输入对象的键的顺序迭代输入对象的键,并在输出对象中设置它们,从空对象{}开始:

jq 'input as $in | reduce keys_unsorted[] as $key ({}; .[$key] = $in[$key])' \
  input.json output.json > reordered_output.json

(Note令人困惑的是,第二个输入文件,这里是output.json,被input过滤器引用。
编辑:原来数据是嵌套结构的。虽然缺少示例数据,但让我们将所有对象视为节点,将所有其他数据类型视为叶。为了访问键和值,将keys_unsorted更改为to_entries(目前,见上文),并将逻辑提升为命名过滤器(函数定义),以便可以在objects上递归调用。

def reorder($in; $ref): $ref | reduce to_entries[] as {$key, $value} ({};
  .[$key] = ($in[$key] | objects |= reorder(.; $value))
);
reorder(input; .)

相关问题