Вопрос:

Объединить массивы JSON

arrays json bash jq

7356 просмотра

3 ответа

47 Репутация автора

Поэтому моя цель - объединить файлы JSON и получить этот формат:

{
  "title": "NamesBook",
  "list": [
    {
      "name": "Ajay"
    },
    {
      "name": "Al"
    }
  ]
}

И у меня есть файлы, которые выглядят так:

blahblah.json

{
  "title": "NamesBook",
  "list": [
    {
      "name": "Ajay"
    }
  ]
}

blueblue.json

{
  "title": "NamesBook",
  "list": [
    {
      "name": "Al"
    }
  ]
}

Я могу хранить массив списков всех моих имен в переменной со следующим:

x = jq -s '.[].list' *.json

А потом я планировал добавить переменную в пустой массив в созданном мной файле out.json, который выглядит следующим образом:

{
  "type": "NamesBook",
  "list": []
}

Тем не менее, когда мой сценарий работает над строкой

jq '.list[] += "$x"' out.json'

Это вызывает ошибку JQ:

Невозможно перебрать ноль.

Даже когда я добавляю случайный элемент, появляется та же ошибка. Советы о том, как мне следует поступить? Есть ли в jq другие инструменты, помогающие объединить массивы?

Автор: Waffy Источник Размещён: 02.02.2017 07:48

Ответы (3)


8 плюса

6666 Репутация автора

Вы можете объединить ваши файлы с помощью add (jq 1.3+):

jq -s '.[0].list=[.[].list|add]|.[0]' *.json

или сплющить (JQ 1.5+):

jq -s '.[0].list=([.[].list]|flatten)|.[0]' *.json

[.[].list] - создает массив всех «списочных» массивов

 [
  [
    {
      "name": "Ajay"
    }
  ],
  [
    {
      "name": "Al"
    }
  ]
]

[.[].list]|flatten- выровнять его (или .[].list|add- сложить все массивы вместе)

[
  {
    "name": "Ajay"
  },
  {
    "name": "Al"
  }
]

.[0].list=([.[].list]|flatten)|.[0] - заменить первый «список» на объединенный, вывести его.

{
  "title": "NamesBook",
  "list": [
    {
      "name": "Ajay"
    },
    {
      "name": "Al"
    }
  ]
}
Автор: zeppelin Размещён: 02.02.2017 09:05

7 плюса

97627 Репутация автора

Предполагая, что каждый файл будет одинаковым, titleа вы просто комбинируете listсодержимое, вы можете сделать это:

$ jq 'reduce inputs as $i (.; .list += $i.list)' blahblah.json blueblue.json

Это просто берет первый элемент и добавляет в свой список список всех остальных входов.

Автор: Jeff Mercado Размещён: 02.02.2017 10:25

1 плюс

41175 Репутация автора

В ОП не указано, что должно произойти, если существуют объекты, для которых .title не является «NamesBook». Если цель состоит в том, чтобы выбрать объекты с .title, равным «NamesBook», можно написать:

map(select(.title == "NamesBook"))
| {title: .[0].title, list: map( .list ) | add}

Это предполагает, что jq вызывается с опцией -s.

Кстати, addэто путь сюда: просто и быстро.

Автор: peak Размещён: 03.02.2017 08:10
Вопросы из категории :
32x32