jsonを比較する際にkeyとvalueの組が同じでもkeyの並びが微妙に違っていたりして余計な差分が出てキレそうなとき、jqを使ってkeyでソートしてからdiffを取ったりすると便利だよっていう小ネタを紹介する。
jq
jqはjsonをいい感じに整形したり、色付け表示したり、フィルタリングしたり、集計したりできる人気のCLIパッケージ。
Web APIから返ってきたjsonを見やすく表示したり、特定keyのvalueが◯◯なエントリだけを抽出する、といった用途で自分は良く使っている。
minifyされたjson読みづらい問題
Web APIなどから返ってくるJSONはminifyされていることが多く、そのままでは読みづらいがjqに食わせることでいい感じに整形 & 色付け表示してくれる。
生json:
{"name": "pinkumohikan", "age": 99999999, "bio": "天才天才天才天才天才天才天才天才天才天才天才天才天才天才天才天才天才技術者", "location": "Japan", "hobby": ["AirsoftGun", "Programming", "EC", "Bowling", "Darts"]}
jqに食わせたもの:
jsonのkeyの並びが地味に違っていてdiff取りづらい問題
2つのjsonが同一であるかを検証したいとき、愚直にdiffを取るとkeyの順序で悩まされることがある。
例:
$ cat a.json b.json { "tako": "wasa", "banana": "dayo", "akkan": "be" } { "akkan": "be", "banana": "dayo", "tako": "wasa" } $ diff a.json b.json 2c2 < "tako": "wasa", --- > "akkan": "be", 4c4 < "akkan": "be" --- > "tako": "wasa"
これらはkeyとvalueの組み合わせで考えると同じなので差分として出ないようにしたい。
jsonのkeyでソートすれば差分を抑えられる
jqにはkeyでソートしてくれる機能があるので、それを使ってkeyでソートしたあとdiffを取れば余計な差分を抑えることができる。
オプションは --sort-keys
または -S
。
man:
o --sort-keys / -S: Output the fields of each object with the keys in sorted order.
例:
$ jq --sort-keys . a.json b.json { "akkan": "be", "banana": "dayo", "tako": "wasa" } { "akkan": "be", "banana": "dayo", "tako": "wasa" }
これらをdiffに食わせれば...
$ diff <(jq --sort-keys . a.json) <(jq --sort-keys . b.json)
余計なdiffを抑えられる。