LoginSignup
9
4

More than 3 years have passed since last update.

【jq】複数のjsonオブジェクトを1つの配列にする方法

Posted at

はじめに

以下のような複数の json オブジェクトを、jqを用いて 1 つの配列に格納する方法を調べました。

{ "name": "JSON" }
{ "name": "XML" }

結論

-s オプション、あるいは -n オプションを用います。

-s オプション

$ echo '
    { "name": "JSON" }
    { "name": "XML" }
    ' | jq -s .
output.json
[
  {
    "name": "JSON"
  },
  {
    "name": "XML"
  }
]

-n オプション

$ echo '
    { "name": "JSON" }
    { "name": "XML" }
    ' | jq -n [inputs]
output.json
[
  {
    "name": "JSON"
  },
  {
    "name": "XML"
  }
]

そのまま jq に流した場合

, で区切られずに出力されます。

$ echo '
    { "name": "JSON" }
    { "name": "XML" }
    ' | jq .
output.json
{
  "name": "JSON"
}
{
  "name": "XML"
}

jq .[] で出力される結果を、配列に格納する場合

jq .[] で出力される結果を配列に格納する場合は、フィルター全体を配列で囲うことで、配列化できます。

$ JSON='
[
    {
        "name": "JSON",
        "good": true
    },
    {
        "name": "XML",
        "good": false
    }
]
'

オプション無しだと、,が存在しないが、

$ echo $JSON | jq '.[] | {name: .name}'

output.json
{
  "name": "JSON"
}
{
  "name": "XML"
}

フィルター全体を[]で囲うことで、配列化できます。

$ echo $JSON | jq '[.[] | {name: .name}]'

output.json
[
  {
    "name": "JSON"
  },
  {
    "name": "XML"
  }
]

もちろん、 -s-nも使用可能。その場合は、jqの結果をパイプでjqにわたす必要があります。

$ echo $JSON \
  | jq '.[] | {name: .name}' \
  | jq -s '.'

output.json
[
  {
    "name": "JSON"
  },
  {
    "name": "XML"
  }
]

詳細

-s オプション

--slurp/-s:
Instead of running the filter for each JSON object in the input, read the entire input stream into a large array and run the filter just once.

公式のマニュアルにある通り、通常jqは入力ストリームを空白文字列で区切り、それぞれの json オブジェクトに対してフィルター処理を適用します。

-sを使用した場合、それぞれの json オブジェクトに対してフィルター処理を適用せず、入力ストリームを 1 つの大きな配列として読み込んだ後、フィルター処理を 1 度だけ実行します。

-n オプション

--null-input/-n:
Don't read any input at all! Instead, the filter is run once using null as the input. This is useful when using jq as a simple calculator or to construct JSON data from scratch.

-nを使用した場合、渡された入力ストリームを読まずにnullを入力ストリームとしてフィルター処理を行います。

$ echo $JSON | jq '.[] | {name: .name}' | jq -n '.'
# null

これと、 jqI / O処理inputsを組み合わせます。

inputs
Outputs all remaining inputs, one by one.

This is primarily useful for reductions over a program's inputs.

inputsに、(残り1の)全ての入力ストリームが格納されているため、inputsを配列で囲ってあげることで、-sと同様の出力が可能になります。

参考


  1. inputsに格納されている「残りの全ての入力ストリーム」とは
    inputsの他にinputがあります。inputinputsを併用している場合、inputで出力した残りがinputsに格納されます。 


    # 全件
    $ echo $JSON | jq '.[] | {name: .name}' | jq -n '{inputs:[inputs]}'
    # {
    #   "inputs": [
    #     {
    #       "name": "JSON"
    #     },
    #     {
    #       "name": "XML"
    #     }
    #   ]
    # }
    
    # `input` を1回使用後、 `inputs` を使用する
    $ echo $JSON | jq '.[] | {name: .name}' | jq -n '{input: input, inputs:[inputs]}'
    # {
    #   "input": {
    #     "name": "JSON"
    #   },
    #   "inputs": [
    #     {
    #       "name": "XML"
    #     }
    #   ]
    # }
    
    # `input` を2回使用後、 `inputs` を使用する
    $ echo $JSON | jq '.[] | {name: .name}' | jq -n '{input: input, input2: input, inputs:[inputs]}'
    
    # {
    #   "input": {
    #     "name": "JSON"
    #   },
    #   "input2": {
    #     "name": "XML"
    #   },
    #   "inputs": []
    # }
    

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4