JQ объединить два json файлов и создать ключ в качестве имени файла для каждого в объединенном файле - PullRequest
1 голос
/ 16 января 2020

Вопрос :

Как объединить несколько файлов JSON, используя jq. Каждый из объединенных объектов должен иметь свое собственное имя ключа в конечном объединенном файле.

file1. json:

{
  "shoe": 0,
  "temp": "10"
}

file2. json:

{
  "num": {
    "sock": 0,
    "ratio": {
      "cat": 100,
      "dog": 0
    }
  },
  "hair": "blue"
}

Требуемый объединенный вывод :

{
  "file1": {
    "shoe": 0,
    "temp": "10"
  },
  "file2": {
    "num": {
      "sock": 0,
      "ratio": {
        "cat": 100,
        "dog": 0
      }
    },
    "hair": "blue"
  }
}

Попытка 1: проблема с приведенным ниже состоит в том, что иерархия объектов объединяется, если это имеет смысл:

jq --slurp 'add' file1.json file2.json

Попытка 1 Вывод (не то, что я хочу) :

{
  "shoe": 0,
  "temp": "10"
  "num": {
    "sock": 0,
    "ratio": {
      "cat": 100,
      "dog": 0
    }
  },
  "hair": "blue"
}

1 Ответ

3 голосов
/ 16 января 2020

jq имеет встроенную переменную input_filename, которая представляет имя файла, к которому применяется фильтр. Таким образом, вы можете сделать что-то вроде

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

Выражение reduce принимает все входные объекты и создает конечный JSON с ключом в качестве используемого имени файла.

Вы можете go на один уровень дальше и хотите дополнительно удалить часть расширения JSON .json, используйте доступные функции обрезки. В приведенном ниже коде предполагается, что входной файл заканчивается на .json и не будет работать с любыми другими расширениями

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