jq 合并两个 json 文件并在合并文件中为每个文件创建一个键作为文件名

Gus*_*ler 3 json jq

问题

如何使用 jq 合并多个 JSON 文件。每个合并的对象在最终合并的文件中都必须有自己的键名。

文件 1.json

{
  "shoe": 0,
  "temp": "10"
}
Run Code Online (Sandbox Code Playgroud)

file2.json

{
  "num": {
    "sock": 0,
    "ratio": {
      "cat": 100,
      "dog": 0
    }
  },
  "hair": "blue"
}
Run Code Online (Sandbox Code Playgroud)

所需的合并输出

{
  "file1": {
    "shoe": 0,
    "temp": "10"
  },
  "file2": {
    "num": {
      "sock": 0,
      "ratio": {
        "cat": 100,
        "dog": 0
      }
    },
    "hair": "blue"
  }
}
Run Code Online (Sandbox Code Playgroud)

尝试 1:下面的问题是,如果有意义的话,对象层次结构会被合并:

jq --slurp 'add' file1.json file2.json
Run Code Online (Sandbox Code Playgroud)

尝试 1 输出(不是我想要的)

{
  "shoe": 0,
  "temp": "10"
  "num": {
    "sock": 0,
    "ratio": {
      "cat": 100,
      "dog": 0
    }
  },
  "hair": "blue"
}
Run Code Online (Sandbox Code Playgroud)

Ini*_*ian 5

jq有一个内置变量 input_filename,表示应用过滤器的文件名。所以你可以做类似的事情

jq -n 'reduce inputs as $s (.; .[input_filename] += $s)'  file1.json file2.json
Run Code Online (Sandbox Code Playgroud)

reduce表达式采用整个输入对象并使用键作为正在使用的文件名构造最终的 JSON。

您可以更进一步,并希望有选择地删除 JSON 的扩展部分.json,使用可用的修剪功能。下面的代码假设输入文件以 结尾.json并且不适用于任何其他扩展名

jq -n 'reduce inputs as $s (.; (.[input_filename|rtrimstr(".json")]) += $s)'
Run Code Online (Sandbox Code Playgroud)