web-dev-qa-db-ja.com

JSONの配列のマージ

だから私の目的は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エラーが表示されます。

Nullを反復することはできません。

ランダムな要素を追加しても、同じエラーが表示されます。どのようにすればよいのか?配列のマージを実現するのに役立つ他のツールがjqにありますか?

11
Waffy

add(jq 1.3+)でファイルをマージできます:

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

またはflatten(jq 1.5+):

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

_[.[].list]_-すべての「リスト」配列の配列を作成します

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

_[.[].list]|flatten_-flatten it(または_.[].list|add_-addすべての配列を一緒に)

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

.[0].list=([.[].list]|flatten)|.[0]-最初の「リスト」をマージされたリストに置き換えて出力します。

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

すべてのファイルが同じtitleを持ち、単にlistの内容を組み合わせるとすると、次のようになります。

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

これは最初のアイテムを取り、そのリストに他のすべての入力のリストを追加するだけです。

8
Jeff Mercado

OPは、.titleが「NamesBook」ではないオブジェクトがある場合にどうするかを指定しませんでした。意図が.titleが「NamesBook」に等しいオブジェクトを選択することである場合、次のように書くことができます。

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

これは、jsが-sオプションを指定して呼び出されることを前提としています。

ちなみに、addはここに行く方法です。シンプルで高速です。

2
peak