はじめに
以下のような複数の json オブジェクトを、jq
を用いて 1 つの配列に格納する方法を調べました。
{ "name": "JSON" }
{ "name": "XML" }
結論
-s
オプション、あるいは -n
オプションを用います。
-s
オプション
$ echo '
{ "name": "JSON" }
{ "name": "XML" }
' | jq -s .
[
{
"name": "JSON"
},
{
"name": "XML"
}
]
-n
オプション
$ echo '
{ "name": "JSON" }
{ "name": "XML" }
' | jq -n [inputs]
[
{
"name": "JSON"
},
{
"name": "XML"
}
]
そのまま jq に流した場合
,
で区切られずに出力されます。
$ echo '
{ "name": "JSON" }
{ "name": "XML" }
' | jq .
{
"name": "JSON"
}
{
"name": "XML"
}
jq .[]
で出力される結果を、配列に格納する場合
jq .[]
で出力される結果を配列に格納する場合は、フィルター全体を配列で囲うことで、配列化できます。
$ JSON='
[
{
"name": "JSON",
"good": true
},
{
"name": "XML",
"good": false
}
]
'
オプション無しだと、,
が存在しないが、
$ echo $JSON | jq '.[] | {name: .name}'
{
"name": "JSON"
}
{
"name": "XML"
}
フィルター全体を[]
で囲うことで、配列化できます。
$ echo $JSON | jq '[.[] | {name: .name}]'
[
{
"name": "JSON"
},
{
"name": "XML"
}
]
もちろん、 -s
や-n
も使用可能。その場合は、jq
の結果をパイプでjq
にわたす必要があります。
$ echo $JSON \
| jq '.[] | {name: .name}' \
| jq -s '.'
[
{
"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
これと、 jq
のI / 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
と同様の出力が可能になります。
参考
- jq Manual (development version)
- How to convert a JSON object stream into an array with jq - Stack Overflow
- jq コマンドを使う日常のご紹介 - Qiita
-
inputs
に格納されている「残りの全ての入力ストリーム」とは
inputs
の他にinput
があります。input
とinputs
を併用している場合、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": [] # }