⭐️
jqの使い方まとめ
jqの使い方でハマったところや便利な使い方をまとめます。
, []などをあとから追加する方法
ちょっと前までは,
がなかったらerrorが出てた気がするんですが(気のせいか?)、今では,
がなくても以下のようなjsonでもerrorが出ないので、あとから追加する方法が使えます。[1]
とかしたいので、[]
も追加します。
jq -s ".|= .+[]"
{
"user" : "syui",
"id" : "1"
}
{
"user" : "test",
"id" : "2"
}
$ cat tmp.json|jq -s ".|= .+[]"
[
{
"user" : "syui",
"id" : "1"
},
{
"user" : "test",
"id" : "2"
}
]
U+0000のerrorが出る場合
jq-1.5
から改行が含まれていると、以下のようなerrorが出る場合があって、これが本当に厄介です。
$ echo "{\"text\":\"$text\"}"|jq .
parse error: Invalid string: control characters from U+0000-through-U+001F must be escaped at line 3, column 23
主な回避策は以下。特殊文字などが含まれている場合も有効です。
-
jq -n --arg var "$var"
-
jq -R tmp.txt
$ jq -n --arg text "$text" "{\"text\":\$text}"
$ text=`echo $text | jq -R`
$ echo "{\"text\":$text}" | jq .
\$text
や$text
の違いに注意してください。
改行を削除する場合
jq <<< $text
$ jq . <<< $text
ダブルクオーテーションを取り除く場合
これは-r
のオプションですね。よく使いますが見落としがちかもしれません。
jq -r ".user"
$ cat tmp.json|jq -r ".[].user"
syui
test
keyを指定して値を取り出す場合
jq "select(.name == \"syui\")
$ cat tmp.json
[
{
"user" : "syui",
"id" : "1"
},
{
"user" : "test",
"id" : "2"
}
]
$ cat tmp.json|jq -r ".[]|select(.user == \"syui\")"
{
"user": "syui",
"id": "1"
}
keyがあればそのkeyの値を取り出す場合
null
じゃなければという条件で検索します。
jq "select(.user !=null)"
$ cat tmp.json
[
{
"user" : "syui",
"id" : "1"
},
{
"user" : "test",
"id" : "2"
}
]
$ cat tmp.json|jq -r ".[]|select(.user !=null)|.user"
syui
test
配列の数を調べる場合
jq length
$ cat tmp.json
[
{
"user" : "syui",
"id" : "1",
"link" : "syui.cf"
},
{
"user" : "test",
"id" : "2",
"link" : "example.com"
}
]
$ cat tmp.json|jq length
2
$ cat tmp.json|jq ".[]|length"
3
3
$ cat tmp.json|jq ".[]|select(.user == \"syui\")|length"
3
keyがあるか調べる場合
jq "has(\"user\")"
$ cat tmp.json|jq ".[]|has(\"user\")"
true
true
2つのファイルをマージする場合
jq -s add tmp.json tmp2.json
以下の2つのファイルがあったとします。
[
{
"user" : "syui",
"id" : "1",
"link" : "syui.cf"
},
{
"user" : "test",
"id" : "2",
"link" : "example.com"
},
{
"user" : "github",
"id" : "3",
"link" : "github.com"
},
]
[
{
"user" : "github",
"id" : "3",
"link" : "github.com"
},
{
"user" : "zenn",
"id" : "4",
"link" : "zenn.dev"
}
]
これらをまとめるには単純にjq -s add
します。
$ jq -s add tmp.json tmp2.json
[
{
"user": "syui",
"id": "1",
"link": "syui.cf"
},
{
"user": "test",
"id": "2",
"link": "example.com"
},
{
"user": "github",
"id": "3",
"link": "github.com"
},
{
"user": "github",
"id": "3",
"link": "github.com"
},
{
"user": "zenn",
"id": "4",
"link": "zenn.dev"
}
]
重複するkeyがあるファイルをマージする場合
これは両者が同じkeyを有する場合のみ有効です。以下の2つのファイルではuser:syui
が重複しています。
したがって、単純にadd
すると2つとも残ってしまいます。
これを1つに統合したいような場面を想定しています。
jq -s '.[0] * .[1]' tmp.json tmp2.json
{
"var": {
"aaa": {
"user": "syui",
"id": "1",
"link": "syui.cf"
},
"bbb": {
"user": "test",
"id": "2",
"link": "example.com"
}
}
}
{
"var": {
"aaa": {
"user": "syui",
"id": "1",
"link": "syui.cf"
},
"ccc": {
"user": "github",
"id": "3",
"link": "github.com"
}
}
}
$ jq -s '.[0] * .[1]' tmp.json tmp2.json
{
"var": {
"aaa": {
"user": "syui",
"id": "1",
"link": "syui.cf"
},
"bbb": {
"user": "test",
"id": "2",
"link": "example.com"
},
"ccc": {
"user": "github",
"id": "3",
"link": "github.com"
}
}
}
keyの複数検索をする場合
jq ".[]|.user,.id"
$ cat tmp.json|jq ".[]|.user,.id"
"syui"
"1"
"test"
"2"
"github"
"3"
配列番号で配列を取り出す場合
jq ".[1]"
$ cat tmp.json|jq "keys|.[]"
0
1
2
$ cat tmp.json|jq ".[1]"
{
"user": "test",
"id": "2",
"link": "example.com"
}
なお、0
から始まるので最初の配列を取り出したければ、.[0]
とします。
keyだけ取り出す場合
jq ".[]|keys"
$ cat tmp.json|jq ".[]|keys|.[]"
"id"
"link"
"user"
"id"
"link"
"user"
"id"
"link"
"user"
Discussion