JSONファイルをコマンドで扱える「jq」を学習してみる #2「データの取り扱い」

2015年4月14日

jq プログラミング 特集

jqコマンドの設置をして、色々触っていると、僕が少し勘違いしていることに気がついた。 jqコマンドは、jsonデータのパース処理を行うだけの、リーダーツールとして考えていたのだが、どうやら、SQLのような操作を行うことが可能という事がわかった。

基本情報

Manual http://stedolan.github.io/jq/manual/ マニュアルの日本語訳 http://dev.classmethod.jp/tool/jq-manual-japanese-translation-roughly/

テスト用データ

{ "alpha":{ "sunday":[ {"book":1500}, {"food":2000}, {"fasion":5000} ] }, "beta":{ "monday":[ {"book":500}, {"food":1200}, {"fasion":12000} ] }, "gamma":{ "fryday":[ {"book":400}, {"food":800}, {"fassion":1000} ] } }

データの取得

root階層パーサー「.」

$ jq ‘.’ data3.json

「alpha->sunday->food」にアクセスする

$ jq '.alpha.sunday[1].food' data3.json 2000M

2つ以上を対象にする

$ jq '.alpha.sunday[1],.alpha.sunday[2]' data3.json { "food": 2000 } { "fassion": 5000 }

配列の取得

配列全て

$ jq '.alpha.sunday[]' data3.json { "book": 1500 } { "food": 2000 } { "fassion": 5000 }

配列を範囲指定する(0以上 2未満)

$ jq '.alpha.sunday[0:2]' data3.json [ { "book": 1500 }, { "food": 2000 } ]

配列の中の要素数を求めます

$ echo '["a","b","c"]' | jq '. | length' 3

表示フォーマットの調整

「|」(パイプ)でつなぐと、取得したデータの表示フォーマットを成形できます。

.alphaのデータを取得して「output」データとして出力する

$ jq '.alpha | {output:.}' data3.json { "output": { "sunday": [ { "book": 1500 }, { "food": 2000 }, { "fassion": 5000 } ] } }

型の種類

通常のJSONフォーマットの型をサポートしているので、大きな問題は発生しないでしょう。 JavaScriptと少し違う点はfunction値が無いという点だけでしょうか。 あと、JavaScript以外の言語でjsonを扱う時に、key値を"**"のようにクォートしなければいけない点に注意しないといけません。
  1. 数値
  2. 文字列
  3. boolean
  4. 配列
  5. オブジェクト(key:value)
  6. null

演算子

出力する値は、演算子を用いて、計算結果を求めることができます。

数値演算 (book + food)

$ jq '.alpha.sunday[0].book + .alpha.sunday[1].food' data3.json 3500

配列演算 (対象のkeyを削除します。)

$ echo '["a","b","c"]' | jq '. - ["a","c"]' [ "b" ]

関数

基本: length (オブジェクト※または配列の要素数を取得)

$ echo '{"a":1,"b":2,"c":3}' | jq '. | length' 3

keys (keyの値の一覧を取得)

$ echo '{"a":1,"b":2,"c":3}' | jq '. | keys' [ "a", "b", "c" ]

has (keyのis-null判定※結果はtrye,falseで返る)

$ echo '{"a":1,"b":2,"c":3}' | jq 'has("a")' true $ echo '{"a":1,"b":2,"c":3}' | jq 'has("d")' false

型変換 : 基本

$ echo '[10, "10"]' | jq '.[]' 10 "10"

tostring (全ての要素を文字列に型変換)

$ echo '[10, "10"]' | jq '.[] | tostring' "10" "10"

tonumber (文字列を数値に型変換)

$ echo '[10, "10"]' | jq '.[] | tonumber' 10 10

情報表示

type (型を表示)

$ echo '[123,true,[1,2],{"a":1,"b":2},null,"abc"]' | jq 'map(type)' [ "number", "boolean", "array", "object", "null", "string" ]

条件、計算

select (条件に一致する結果のみを表示する)

$ echo '{"a":1,"b":2,"c":3}' | jq '.[] | select(. >= 2)' 2 3

add (配列の結合)

## 数値の場合は、全ての合計値 $ echo '[1,2,3]' | jq 'add' 6

文字列の場合は、全ての結合

$ echo '["abc","def","ghi"]' | jq 'add' "abcdefghi"

range (範囲の数値を配列で作成する)

$ echo null | jq 'range(5;10)' 5 6 7 8 9 $ echo null | jq '[range(5;10)]' [ 5, 6, 7, 8, 9 ]

SQL-like

sort (値の結果をソート)

$ echo '[2,5,10,1,6,0,null]' | jq 'sort' [ null, 0, 1, 2, 5, 6, 10 ]

sort_by(**) [**keyの値でソートする]

$ echo '[{"a":11,"b":1},{"a":1,"b":2},{"a":31,"b":3}]' | jq 'sort_by(.a)' [ { "a": 1, "b": 2 }, { "a": 11, "b": 1 }, { "a": 31, "b": 3 } ]

group_by (対象のkeyをグループ化して処理する)

$ echo '[{"a":11,"b":1},{"a":1,"b":1},{"a":31,"b":3}]' | jq 'group_by(.b)' [ [ { "a": 11, "b": 1 }, { "a": 1, "b": 1 } ], [ { "a": 31, "b": 3 } ] ]

min,max,min_by(*),max_by(*)

$ echo '[2,5,10,1,6,0,null]' | jq 'min' null $ echo '[2,5,10,1,6,0,null]' | jq 'max' 10 $ echo '[{"a":11,"b":1},{"a":1,"b":2},{"a":31,"b":3}]' | jq 'max_by(.a)' { "a": 31, "b": 3 }

unique (重複の値を削除する)

$ echo '[0,0,1,1,2,2,3,4,4,5,5]' | jq 'unique' [ 0, 1, 2, 3, 4, 5 ]

reverse (昇順に表示)

$ echo '[0,0,1,1,2,2,3,4,4,5,5]' | jq 'unique | reverse' [ 5, 4, 3, 2, 1, 0 ]

contains (完全一致の要素が含まれているかbooreanを返す)

$ echo '[{"a":11,"b":1},{"a":1,"b":2},{"a":31,"b":3}]' | jq '.[] | contains({a:11})' true false false

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。