JSON を整形して出力することができます。
$ echo '{"a":123, "b":456}' | jq { "a": 123, "b": 456 }
JSON の中から指定したキーや配列の情報を取り出すことができます。
$ echo '{"a":123, "b":456}' | jq '.b' 456
JSON の中から、age が 40 以下などの条件を指定して取り出すこともできます。
$ cat sample.json | jq -c '.users[] | select(.age <= 40)' {"name":"Yamada","age":26} {"name":"Tanaka","age":32}
JSON データを整形することもできます。
$ cat sample.json | jq -rc '.users[] | "\(.name)(\(.age))"' Yamada(26) Tanaka(32) Suzuki(45)
合計値を求めることもできます。
$ cat sample.json | jq '[.users[].age] | add' 103
簡単な計算ツールとして使用することもできます。
$ jq -n '60 * 60 * 24' 86400
簡単なコンバートツールとして使用することもできます。
$ echo '"x > y"' | jq -r '@html' x > y
# RHEL8系 # yum -y install jq # RHEL7系 # yum -y install epel-release # yum -y install jq # Ubuntu 22.04 # apt -y install jq
本書では、サンプルとして下記の JSON を使用します。
{ "status": "OK", "count": 3, "users": [ { "name": "Yamada", "age": 26 }, { "name": "Tanaka", "age": 32 }, { "name": "Suzuki", "age": 45 } ] }
jq [options] jq [options] filter [file...] jq [options] --args filter [arguments...] jq [options] --jsonargs filter [json_texts...]
例えば下記の様に使用します。
$ cat sample.json | jq $ cat sample.json | jq '.users' $ jq '.users' sample.json
インデント文字数を指定します。
$ echo '{"name": "Yamada"}' | jq --indent 4 { "name": "Yamada" }
インデントにタブ文字を使用します。
$ echo '{"name": "Yamada"}' | jq --tab { "name": "Yamada" }
改行やインデント無しのコンパクト形式で出力します。
$ echo '{"name": "Yamada"}' | jq -c {"name": "Yamada"}
キーをソートして出力します。
$ echo '{"b":"B", "c":"C", "a":"A"}' | jq -S { "a": "A", "b": "B", "c": "C" }
色つきで出力します。色は JQ_COLORS でカスタマイズできます。
$ echo '{"name": "Yamada"}' | jq -C { "name": "Yamada" }
色無しで出力します。
$ echo '{"name": "Yamada"}' | jq -M { "name": "Yamada" }
出力データの文字列のダブルクォーテーションを取り除きます。
$ echo '{"name":"Yamada"}' | jq '.name' "Yamada" $ echo '{"name":"Yamada"}' | jq -r '.name' Yamada
-r と似ていますが、個々の出力の末尾に改行を出力しません。
$ echo '{"name":"Yamada"}{"name":"Tanaka"}' | jq -j '.name' YamadaTanaka
非ASCII文字を ASCII文字で出力します。
$ echo '{"name":"山田"}' | jq -c {"name":"山田"} $ echo '{"name":"山田"}' | jq -c -a {"name":"\u5c71\u7530"}
Windows 利用者がこのオプションを使用すると、jq.exe が LF を CR LF に変換するのを抑制することができます。
C:\Temp> jq.exe -b ...
出力をバッファリングしないようにします。
$ tail -f xxx.log | jq --unbuffered > xxx.json
JSON列(複数のJSON)を読み取り、配列に変換します。
$ echo '{"name":"Yamada"}{"name":"Suzuki"}' | jq -c {"name":"Yamada"} {"name":"Suzuki"} $ echo '{"name":"Yamada"}{"name":"Suzuki"}' | jq -c -s [{"name":"Yamada"},{"name":"Suzuki"}]
入力を JSON としてではなく、改行で区切られた文字列の集合として扱います。
$ cat xx.csv Yamada,26 Tanaka,32 $ cat xx.csv | jq -c -R 'split(",")' ["Yamada","26"] ["Tanaka","32"]
入力を読み込まず、引数で指定した文字列を JSON として扱います。
$ jq -n '{"name":"Yamada"}' { "name": "Yamada" }
入力を application/json-seq 型のデータとして扱います。複数個の JSON データを、JSON データの先頭に RS(U+001E)、末尾に LF(U+000A) を付けて並べた形式です。あまり利用されていません。
$ cat json-seq.json | js --seq '...'
$key に value を割り当てます。
$ jq -nc --arg name Yamada '{"name": $name}' {"name": "Yamada"}
$key に JSON値 value を割り当てます。
$ jq -cn --argjson foo '{"name":"Yamada"}' '{"foo":$foo}' {"foo":{"name":"Yamada"}}
$key に filename で指定したファイルの中身を割り当てます。
$ echo '{"name":"Yamada"}{"name":"Tanaka"}' > sample.json $ jq -nc --slurpfile foo sample.json '{"foo":$foo}' {"foo":[{"name":"Yamada"},{"name":"Tanaka"}]}
--slurpfile と同様ですが、ファイルの内容が1行の場合のみ利用できます。
$ echo -n '"Yamada"' > sample.raw $ jq -nc --argfile foo sample.raw '{"foo":$foo}' {"foo":"Yamada"}
$key に filename で指定したファイルの中身(RAWデータ)を割り当てます。
$ echo -n Yamada > sample.raw $ jq -nc --rawfile foo sample.raw '{"foo":$foo}' {"foo":"Yamada"}
パラメータを引数で指定します。パラメータは $ARG.positional で参照することができます。
$ jq -nc --args '$ARGS' AAA BBB {"positional":["AAA","BBB"],"named":{}}
パラメータを JSON 形式で指定します。パラメータは $ARG.positional で参照することができます。
$ jq -nc --jsonargs '$ARGS' '{"arg1":"AAA","arg2":"BBB"}' {"positional":[{"arg1":"AAA","arg2":"BBB"}],"named":{}}
バージョンを表示します。
$ jq --version jq-1.6
ヘルプを表示します。
$ jq --help
フィルタ情報をコマンドラインからではなくファイルで指定します。
$ cat sample.jq .name $ echo '{"name":"Yamada"}' | jq -f sample.jq "Yamada"
入力をストリーム的に読込み、ひとつの値を、[[値のパス配列],値] の列に変換しながら処理します。JSON が完了していなくても値毎に逐次処理できるため、巨大な JSON ファイルを逐次処理する際に利用されます。
$ cat sample.json | jq -c --stream [["status"],"OK"] [["count"],3] [["users",0,"name"],"Yamada"] [["users",0,"age"],26] [["users",0,"age"]] [["users",1,"name"],"Tanaka"] [["users",1,"age"],32] [["users",1,"age"]] [["users",2,"name"],"Suzuki"] [["users",2,"age"],45] [["users",2,"age"]] [["users",2]] [["users"]]
include や import で読み込むライブラリファイルのパス名を指定します。
$ cat sample.json | jq -L /usr/local/lib/jq -f sample.jq
jq コマンド通常の終了コードは、0(正常終了)、2(利用方法エラーやシステムエラー)、3(コンパイルエラー) となりますが、-e を指定すると最後に処理したデータが false や null でなければ 0、false や null であれば 1、有効な結果が得られなければ 4 を返します。
$ echo 'null' | jq -e ; echo $? null 1
JSON からキーを指定して値を取り出すことができます。
.key は該当するキーの値を取り出します。
$ cat sample.json | jq '.status' "OK"
カンマ(,)で複数の値を取り出すこともできます。
$ cat sample.json | jq '.status, .count' "OK" 3
配列要素を抽出します。
$ cat sample.json | jq -c '.users' [{"name":"Yamada","age":26},{"name":"Tanaka","age":32},{"name":"Suzuki","age":45}] $ cat sample.json | jq -c '.users[]' {"name":"Yamada","age":26} {"name":"Tanaka","age":32} {"name":"Suzuki","age":45}
0から数えて n番目の要素を取り出します。
$ cat sample.json | jq -c '.users[1]' {"name":"Tanaka","age":32}
最後から n番目の要素を取り出します。
$ cat sample.json | jq -c '.users[-1]' {"name":"Suzuki","age":45}
n~m番目の要素を配列形式で取り出します。
$ cat sample.json | jq -c '.users[0:2]' [{"name":"Yamada","age":26},{"name":"Tanaka","age":32}]
結果の JSON に対してさらに jq で抽出を行うことができます。複数の jq コマンドを連結することもできますが、パイプ(|)で連結することにより、一つ目のフィルタで抽出した結果を入力として再度抽出を行うこともできます。
$ cat sample.json | jq '.users[]' | jq '.name' "Yamada" "Tanaka" "Suzuki" $ cat sample.json | jq '.users[] | .name' "Yamada" "Tanaka" "Suzuki"
ドット(.)で連結することにより、一つ目のフィルタで抽出した結果を入力として再度抽出を行うこともできます。
$ cat sample.json | jq '.users[].name' "Yamada" "Tanaka" "Suzuki"
抽出した列を配列として整形するには全体を [...] で囲みます。
$ cat sample.json | jq -c '[.users[].name]' ["Yamada","Tanaka","Suzuki"]
JSON列を下記の様に名前をキーとした配列に変換することもできます。
$ cat sample.json | jq -c '.users[] | [.name, .age]' ["Yamada",26] ["Tanaka",32] ["Suzuki",45]
オブジェクトとして整形したい場合は全体を {key:...} で囲みます。
$ cat sample.json | jq -c '{name:.users[].name}' {"name":"Yamada"} {"name":"Tanaka"} {"name":"Suzuki"}
下記の様にオブジェクト列にすることもできます。
$ cat sample.json | jq -c '.users[] | {N:.name, A:.age}' {"N":"Yamada","A":26} {"N":"Tanaka","A":32} {"N":"Suzuki","A":45}
下記の例では、名前をキー、年齢を値としたオブジェクトを生成します。キー名を (...) で囲む必要があります。
cat sample.json | jq -c '.users[] | {(.name):.age}' {"Yamada":26} {"Tanaka":32} {"Suzuki":45}
.filter1.filter2.filter3.filterx を途中のフィルタを省略して ..|.filterx と表現することができます。例えば、sample.json からデータ階層に関わらず name の値を抽出するには ..|.name と記述します。.name にマッチしない値もあるため、エラー無視の ? を付加して ..|.name? とし、さらに | strings で文字列のみを抽出します。
$ cat sample.json | jq '..|.name?|strings' "Yamada" "Tanaka" "Suzuki"
x + y # x と y の加算 x - y # x と y の減算 x * y # x と y の乗算 x / y # x と y の除算 x % y # x と y の剰余
x == y # x と y が等しければ x != y # x と y が等しくなければ x > y # x が y より大きければ x >= y # x が y 以上であれば x <= y # x が y 以下であれば x > y # x が y より小さければ
x and y # x かつ y が真であれば x or y # x または y が真であれば not x # x が真でなければ
x // y # x が false や null でなければ x、さもなくば y
左辺のフィルタの値を左辺で更新します。
$ echo '{"flag":true}' | jq -c '.flag |= if . then 1 else 0 end' {"flag":1}
|= と = は似ていますが、下記などの例で差異が分かります。
$ echo '{"a": {"b": 10}, "b": 20}' | jq -c '.a = .b' {"a":20,"b":20} $ echo '{"a": {"b": 10}, "b": 20}' | jq -c '.a |= .b' {"a":10,"b":20}
$ echo '{"foo":42}' | jq -c '.foo += 1' {"foo":43}
JSON列を受け取り、条件にマッチした項目のみを抽出します。
$ echo '[1,2,3,4,5]' | jq -c '.[] | select(. > 2)' 3 4 5 $ echo '[1,2,3,4,5]' | jq -c 'map(select(. > 2))' [3,4,5] $ echo '[{"k":"ABC","v":92},{"k":"DEF","v":76}]' | jq -c '.[] | select(.v > 80)' {"k":"ABC","v":92}
配列やオブジェクトを受け取り、それぞれの値に対してマップ処理を行った結果の配列を返却します。
$ echo '[1,2,3]' | jq -c 'map(. + 1)' [2,3,4]
配列やオブジェクトを受け取り、それぞれの値を、値に対してマップ処理を行った結果で置換したものを返却します。
$ echo '{"a":1,"b":2,"c":3}' | jq -c 'map_values(. + 1)' {"a":2,"b":3,"c":4}
配列の値の合計を求めます。
$ echo '[1,2,3]' | jq -c 'add' 6
配列をソートします。path_expression を指定した場合は指定したキーでソートします。
$ echo '[3,5,1,4,2]' | jq -c 'sort' [1,2,3,4,5] $ echo '[{"A":3,"B":2},{"A":1,"B":3},{"A":2,"B":1}]' | jq -c 'sort_by(.B)' [{"A":2,"B":1},{"A":3,"B":2},{"A":1,"B":3}]
path_expression で指定したキーが同じ値を持つものをグルーピングします。
$ echo '[{"A":1,"B":3},{"A":3,"B":2},{"A":1,"B":1}]' | jq -c 'group_by(.A)' [[{"A":1,"B":3},{"A":1,"B":1}],[{"A":3,"B":2}]]
重複した値をひとつにまとめます。
$ echo '[1,2,3,2,1]' | jq -c 'unique' [1,2,3] $ echo '[{"A":3,"B":1},{"A":1,"B":3},{"A":2,"B":1}]' | jq -c 'unique_by(.B)' [{"A":3,"B":1},{"A":1,"B":3}]
配列の順序を逆順にします。
$ echo '[1,2,3]' | jq -c 'reverse' [3,2,1]
配列を受け取り、配列要素の中に一つでも true または condition が true になるものがあれば true を返します。
$ echo '[false, true, false]' | jq 'any' true $ echo '["A","B","C"]' | jq 'any(.=="B")' true
配列を受け取り、配列要素の中のすべての要素が true または condition が true であれば true を返します。
$ echo '[true, true, true]' | jq 'all' true $ echo '["A","A","A"]' | jq 'any(.=="A")' true
配列の階層をフラットにします。depth を指定すると depth 階層までの配列をフラット化します。
$ echo '[1,[2,[3,4]]]' | jq -c 'flatten' [1,2,3,4] $ echo '[1,[2,[3,4]]]' | jq -c 'flatten(1)' [1,2,[3,4]]
ソート済の配列を入力として値 x をバイナリサーチします。見つかれば見つかった位置のインデックスを、見つからなければ見つからないと判断した位置のインデックスの負数から1引いた値を返却します。
$ echo '[1,3,5,7,9]' | jq 'bsearch(5)' 2 $ echo '[1,3,5,7,9]' | jq 'bsearch(6)' -4
配列の個数、オブジェクトの要素数、文字列の文字数を返します。
$ echo '["a","b","c"]' | jq 'length' 3
UTF-8 で表現した場合のバイト数を返します。
$ echo '"あ"' | jq 'utf8bytelength' 3
パスとして参照されるキー名および配列インデックスの配列を返却します。
$ echo 'null' | jq -c 'path(.a[0].b)' ["a",0,"b"]
パス配列を指定して値を抽出します。
$ echo '{"a":{"b":{"c":123}}}' | jq -c 'getpath(["a", "b", "c"])' 123 "Yamada"
パス配列を指定して値を変更します。
$ echo '{"a":{"b":{"c":123}}}' | jq -c 'setpath(["a", "b", "c"]; 456)' {"a":{"b":{"c":456}}}
パス配列の配列を指定して値を削除します。
$ echo '{"a":{"b":{"c":123}}}' | jq -c 'delpaths([["a", "b", "c"]])' {"a":{"b":{}}}
それぞれの値を得るためのパス配列の一覧を返却します。node_filter に型名を指定すると型にマッチする要素に関してのみ出力します。
$ echo '{"a":123, "b":456, "c":{"d":789}}' | jq -c '[paths]' [["a"],["b"],["c"],["c","d"]] $ echo '{"a":123, "b":456, "c":{"d":789}}' | jq -c '[paths(scalars)]' [["a"],["b"],["c","d"]]
paths(scalars) と同義です。
$ echo '{"a":123, "b":456, "c":{"d":789}}' | jq -c '[leaf_paths]' [["a"],["b"],["c","d"]]
キーのみの配列をソートして返します。
$ echo '{"b":"B", "c":"C", "a":"A"}' | jq -c 'keys' ["a","b","c"]
キーのみの配列をソートせずに返します。
$ echo '{"b":"B", "c":"C", "a":"A"}' | jq -c 'keys_unsorted' ["b","c","a"]
オブジェクトを受け取り、オブジェクトが key キーを持っていれば true、さもなくば false を返します。
$ echo '{"foo":"FOO"}' | jq 'has("foo"), has("baa")' true false
値の配列を受け取り、引数で指定したオブジェクトのキーとして存在すれば true、さもなくば false を返します。
$ echo '["foo","bar","baz"]' | jq '.[] | in({"foo":null})' true false false
{key: value} 形式を {"key":key, "value":value} 形式に変換します。
$ echo '{"a":123,"b":456}' | jq -c 'to_entries' [{"key":"a","value":123},{"key":"b","value":456}]
{"key":key, "value":value} 形式を {key: value} 形式に変換します。
$ echo '[{"key":"a","value":123},{"key":"b","value":456}]' | jq -c 'from_entries' {"a":123,"b":456}
{key: value} の .key や .value に対して変換処理を行います。
$ echo '{"a":123,"b":456}' | jq -c 'with_entries(.key |= "KEY_" + .)' {"KEY_a":123,"KEY_b":456}
値の列を受け取り、型が合致するもののみを抽出します。
$ echo '["ABC",123,[4,5,6]]' | jq -c '.[] | strings' "ABC" $ echo '["ABC",123,[4,5,6]]' | jq -c '.[] | numbers' 123 $ echo '["ABC",123,[4,5,6]]' | jq -c '.[] | arrays' [4,5,6]
値の型を返します。
$ echo '[true, "A", 123, [], {}, null]' | jq -c 'map(type)' ["boolean","string","number","array","object","null"]
エラーメッセージを表示します。
# echo '120' | jq 'if . > 100 then error("TooBIG") else . end' jq: error (at <stdin>:1): TooBIG
プログラムを中断します。
$ echo '[88,92,123]' | jq '.[] | if . > 100 then halt else . end' 88 92
プログラムを中断し、終了コードを返します。
$ jq -n 'halt_error(99)' $ echo $? 99
floor は切り下げ、ceil は切り上げ、round は四捨五入を行います。trunc は切り下げを行いますが、負数の時は数値が小さくなる方向ではなく 0 に近づく方向に丸めます。nearbyint と rint は銀行丸め (偶数+0.5の場合は切り下げ、奇数+0.5の場合は切り上げ)を行います。
$ echo '3.14159' | jq 'floor' 3
最小値、最大値を返します。path_exp を指定すると、指定したキーの値が最小、最大のものを返します。
$ echo '[3,6,1]' | jq 'min' 1 $ echo '[3,6,1]' | jq 'max' 6 $ echo '[{"A":3,"B":2},{"A":1,"B":3},{"A":2,"B":1}]' | jq -c 'min_by(.B)' {"A":2,"B":1} $ echo '[{"A":3,"B":2},{"A":1,"B":3},{"A":2,"B":1}]' | jq -c 'max_by(.B)' {"A":1,"B":3}
pow は x の y乗を求めます。
$ jq -n 'pow(2;16)' 65536
数値の平方根、立方根を求めます。
$ echo '2' | jq 'sqrt' 1.4142135623730951
modf は数値を整数部と小数部に分解し、[小数部, 整数部] を返します。frexp は入力を x とし、x = y(0.5~1.0) * 2 の z 乗が成り立つ [y, z] を返します。
$ echo '3.5' | jq -c 'modf' [0.5,3] $ echo '8.0' | jq -c 'frexp' [0.5,4]
三角関数(sin, cos, tan)、逆三角関数(asin, acos, atan)、双曲線関数(sinh, cosh, tanh)、双曲線逆正弦(asinh, acosh, atanh)です。
$ echo '1.2' | jq 'sin' 0.9320390859672263
対数に関連する数学関数です。
$ echo '2.0' | jq 'log' 0.6931471805599453
オイラー定数 e に関連する数学関数です。
$ echo '1.0' | jq 'exp' 2.718281828459045
その他の数学関数として、誤差関数(erf)、相補誤差関数(erfc)、絶対値(fabs)、ガンマ関数関連(gamma, lgamma, tgamma)、ベッセル関数関連(j0, j1, y0, y1)、仮数(significand) があります。
$ echo '-2.3' | jq 'fabs' 2.3
上記の他、2個の引数をもつ数学関数として、atan2、copysign、drem、fdim、fmax、fmin、fmod、hypot、jn、ldexp、nextafter、nexttoward、remainder、scalb、scalbln、yn があります。3個の引数をもつ数学関数として fma があります。詳細説明省略。
$ jq -n 'atan2(0.1;0.2)' 0.4636476090008061
文字列が str で始まっていれば true を返します。
$ echo '"Japanese"' | jq 'startswith("Jap")' true
文字列が str で終わっていれば true を返します。
$ echo '"Japanese"' | jq 'endswith("ese")' true
先頭から(末尾から) str を取り除いた文字列を返します。
$ echo '"Japanese"' | jq 'ltrimstr("Jap")' "anese" $ echo '"Japanese"' | jq 'rtrimstr("ese")' "Japan"
文字列を文字コードの配列に変換します。
$ echo '"ABC"' | jq -c 'explode' [65,66,67]
文字コードの配列を文字列に変換します。
$ echo '[65,66,67]' | jq 'implode' "ABC"
小文字・大文字に変換します。
$ echo '"Japanese"' | jq 'ascii_downcase' "japanese" $ echo '"Japanese"' | jq 'ascii_upcase' "JAPANESE"
文字列をデリミタで分割して配列にします。正規表現や、正規表現のフラグを指定することもできます。
$ echo '"foo,baa,baz"' | jq -c 'split(",")' ["foo","baa","baz"]
配列をデリミタで連結して文字列にします。
$ echo '["foo","baa","baz"]' | jq 'join(",")' "foo,baa,baz"
入力が文字列の場合、指定した文字列が含まれていれば true を返します。入力が配列の場合、指定した配列要素がすべて含まれていれば true を返します。入力がオブジェクトの場合、指定したパスの値が合致していれば true を返します。
$ echo '"ABCDEFGHIJ"' | jq 'contains("DEF")' true $ echo '["A","B","C"]' | jq 'contains(["A","C"])' true $ echo '{"A":12, "B":13, "D":{"E":14}}' | jq 'contains({"A":12, "D":{"E":14}})' true
文字列や配列の中で s が出現する箇所のインデックスの配列を返します。
$ echo '"Japanese"' | jq -c 'indices("a")' [1,3] $ echo '[1,2,3,4,1,2,1,6]' | jq -c 'indices(1)' [0,4,6] $ echo '[1,2,3,4,1,2,1,6]' | jq -c 'indices([1,2])' [0,4]
文字列や配列の中で s が最初に(最後に)出現する箇所のインデックスを返します。
$ echo '"Japanese"' | jq -c '[index("a"), rindex("a")]' [1,3] $ echo '[1,2,3,4,1,2,1,6]' | jq -c '[index(1), rindex(1)]' [0,6] $ echo '[1,2,3,4,1,2,1,6]' | jq -c '[index(1), rindex([1,2])]' [0,4]
数値の列を引数として受け取り、最大値 n 以下の数値のみを返します。
$ echo '[1,2,3,4,5]' | jq -c '[limit(3;.[])]' [1,2,3]
配列を入力、または列を引数として受け取り、最初、最後、n番目(0開始)の要素を返します。
$ echo '["A","B","C","D","E"]' | jq 'first' "A" $ echo '["A","B","C","D","E"]' | jq 'last' "E" $ echo '["A","B","C","D","E"]' | jq 'nth(3)' "D" $ echo '["A","B","C","D","E"]' | jq 'first(.[])' "A" $ echo '["A","B","C","D","E"]' | jq 'last(.[])' "E" $ echo '["A","B","C","D","E"]' | jq 'nth(3; .[])' "D"
文字列を入力とし、正規表現 reg にマッチすれば true、さもなくば false を返します。
$ echo '"ABC"' | jq 'test("^[A-Z]+$")' true
flags には 何度もマッチする(g)、大文字・小文字を無視する(i)、マルチラインモード(m)、シングルラインモード(s)、m と s 両方を有効化(p)、空マッチを無視(n)、最長マッチ(l)、拡張正規表現マッチ(x) の組み合わせを指定します。
$ echo '"abc"' | jq 'test("^[A-Z]+$"; "i")' true
マッチした箇所のオフセット(offset)、長さ(length)、マッチ文字列(string)、キャプチャ情報(capture) を返します。
$ echo '"23:59:59"' | jq -c 'match("([0-9]+)"; "g")' {"offset":0,"length":2,"string":"23","captures":[{"offset":0,"length":2,"string":"23","name":null}]} {"offset":3,"length":2,"string":"59","captures":[{"offset":3,"length":2,"string":"59","name":null}]} {"offset":6,"length":2,"string":"59","captures":[{"offset":6,"length":2,"string":"59","name":null}]}
キャプチャした文字列にキーを割り当てます。
$ echo '"23:59:59"' | jq -c 'capture("(?<hour>[0-9]+):(?<min>[0-9]+):(?<sec>[0-9]+)")' {"hour":"23","min":"59","sec":"59"}
マッチした文字列を返します。
$ echo '"23:59:59"' | jq -c '[scan("[0-9]+")]' ["23","59","59"]
正規表現 reg で分割したものを配列として返します。
$ echo '"23:59:59"' | jq -c 'split(":") | .[]' ["23","59","59"]
正規表現 reg で分割したものを配列ではなく値の列として返します。
$ echo '"23:59:59"' | jq -c 'split(":") | .[]' ["23","59","59"]
文字列を受け取り、正規表現 reg にマッチする箇所を str に置換します。"g" フラグを指定しなければ最初の1回だけ置換します。
$ echo '"Japanese"' | jq 'sub("e"; "E")' "JapanEse"
文字列を受け取り、正規表現 reg にマッチする箇所を str に置換します。"g" フラグを指定しなくてもすべて置換します。
$ echo '"Japanese"' | jq 'gsub("e"; "E")' "JapanEsE"
文字列を数値に変換します。
$ echo '"1.23"' | jq 'tonumber' 1.23
数値をに文字列変換します。
$ echo '1.23' | jq 'tostring' "1.23"
扱える最大値を返します。
$ jq -n 'infinite' 1.7976931348623157e+308
number 型ではあるけれども、数値ではない値 (Not a Number) を返します。
$ jq -nc '[nan, (nan | type)]' [null,"number"]
何も返却しません。
$ echo '{"a":123, "b":456}' | jq -c '[.a, empty, .b]' [123,456]
環境変数を参照します。
$ jq -n 'env.PATH' "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
現在のファイル名と行数を返します。
$ echo '{"a":123}' | jq '$__loc__' { "file": "<top-level>", "line": 1 }
無限数、NaN、有限数、正規数であるか否かを返します。
$ jq -nc 'infinite | isinfinite' true
exp が empty であれば true、さもなくば false を返します。
$ jq -n 'isempty(empty)' true
組み合わせを返します。n を指定すると n 個の要素を持つ組み合わせを生成します。
$ echo '[[1,2],[3,4]]' | jq -c 'combinations' [1,3] [1,4] [2,3] [2,4] $ echo '[1,2]' | jq -c 'combinations(3)' [1,1,1] [1,1,2] [1,2,1] [1,2,2] [2,1,1] [2,1,2] [2,2,1] [2,2,2]
行列の転置を行います。(→ 転置行列)
$ echo '[[1,2],[3,4],[5,6]]' | jq -c 'transpose' [[1,3,5],[2,4,6]]
入力した文字や要素が s の中に出現すれば true、さもなくば false を返します。
$ echo '"DEF"' | jq 'inside("ABCDEF")' true $ echo '["A"]' | jq 'inside(["A","B","C"])' true
from から upto まで by 毎に加算した数値の列を返します。from を省略すると 0、by を省略すると 1 とみなされます。
$ echo 'null' | jq -c '[range(5)]' [0,1,2,3,4] $ echo 'null' | jq -c '[range(2;7)]' [2,3,4,5,6] $ echo 'null' | jq -c '[range(0;10;2)]' [0,2,4,6,8]
条件式 cond が成り立つ間、update を繰り返して生成される値の配列を返します。
$ echo '1' | jq -c '[while(.<100; .*2)]' [1,2,4,8,16,32,64]
cond が成り立つまで next を繰り返して最終的な値を返します。
$ echo '1' | jq 'until(.>100; .*2)' 128
再帰構造のデータから特定のキーを取り出す際などに利用されます。例えば、下記のようなディレクトリツリーを表す再帰的な構造から name の一覧を取り出すには .name, .dirs[].name, .dirs[].dirs[].name, .dirs[].dirs[].dirs[].name などを取り出す必要がありますが、recurse(.dirs[]) | .name で何階層でもまとめて取り出すことができます。condition は再帰探索を継続する条件を指定します。recurse は recurse(.[]?) と同義です。recurse(f) は recurse(f; .!=null) と同義です。recurse_down は recurse と同義ですが過去互換性のために残されており非推奨です。
$ echo ' {"name": "/", "dirs": [ {"name": "/bin", "dirs": [ {"name": "/bin/ls", "dirs": []}, {"name": "/bin/sh", "dirs": []} ]}, {"name": "/usr", "dirs": [ {"name": "/usr/sbin", "dirs": [ {"name": "/usr/sbin/useradd", "dirs": []}, {"name": "/usr/sbin/usermod", "dirs": []} ]} ]} ]} ' | jq 'recurse(.dirs[]) | .name' "/" "/bin" "/bin/ls" "/bin/sh" "/usr" "/usr/sbin" "/usr/sbin/useradd" "/usr/sbin/usermod"
子要素、孫要素などに対して再帰的に f を適用していきます。
$ echo '[[8,5,2], [4,1,7], [3,6,9]]' | jq -c 'walk(if type=="array" then sort else . end)' [[1,4,7],[2,5,8],[3,6,9]]
初期値を init とします。列 exp のひとつひとつを $val に代入し、update で初期値を変更しながら、extract を実行した結果の列を返却します。
$ echo '[10,20,30,40,50]' | jq -c '[foreach .[] as $n (300; . + $n; .)]' [310,330,360,400,450]
オブジェクトを受け取り指定したキーを削除します。また、配列を受け取り指定したインデックスの要素を削除します。
$ echo '{"foo":"FOO", "baa":"BAA", "baz":"BAZ"}' | jq -c 'del(.foo, .baz)' {"baa":"BAA"} $ echo '["foo", "baa", "baz"]' | jq -c 'del(.[0, 2])' ["baa"]
データを JSON 文字列に変換します。
$ echo '{"name":"Tanaka"}' | jq 'tojson' "{\"name\":\"Tanaka\"}"
JSON 文字列をデータに変換します。
echo '"{\"name\":\"Tanaka\"}"' | jq -c 'fromjson' {"name": "Tanaka"}
ISO 8601 形式の日時文字列を読み込み、1970年1月1日0時0分0秒UTC からの秒数に変換します。fromdate は今後は ISO 8601 以外にも対応するかもしれませんが、現時点では ISO 8601 形式のみに対応します。
$ echo '"2023-12-31T23:59:59Z"' | jq 'fromdate' 1704067199 $ echo '"2023-12-31T23:59:59Z"' | jq 'fromdateiso8601' 1704067199
1970年1月1日0時0分0秒UTC からの秒数を読み込み、ISO 8601 形式の時刻文字列に変換します。
$ echo '1704067199' | jq 'todate' "2023-12-31T23:59:59Z" $ echo '1704067199' | jq 'todateiso8601' "2023-12-31T23:59:59Z"
現在の時刻を 1970年1月1日0時0分0秒UTC からの秒数で返します。
$ jq -n 'now' 1704067199.123456
gmtime は 1970年1月1日0時0分0秒UTC からの秒数 を [年,月,日,時,分,秒,曜日,1年間の中の日数] の配列(UTC)に変換します。月は 0~11 で表すことに注意してください。localtime はローカルタイムに変換します。mktime は配列(UTC)を秒数に変換します。
$ echo '1704067199' | jq -c 'gmtime' [2023,11,31,23,59,59,0,364] $ echo '1704067199' | jq -c 'localtime' [2024,0,1,8,59,59,1,0] $ echo '[2023,11,31,23,59,59,0,364]' | jq -c 'mktime' 1704067199
strptime は文字列をフォーマット指定で配列に変換します。strftime は配列をフォーマット指定で文字列に変換します。strflocaltime はローカルタイムとして変換します。
$ echo '"2023-12-31 23:59:59"' | jq -c 'strptime("%Y-%m-%d %H:%M:%S")' [2023,11,31,23,59,59,0,364] $ echo '[2023,11,31,23,59,59,0,364]' | jq -c 'strftime("%Y/%m/%d %H:%M:%S")' "2023/12/31 23:59:59" $ echo '[2023,11,31,23,59,59,0,364]' | jq -c 'strflocaltime("%Y-%m-%d %H:%M:%S")' "2023-12-31 23:59:59"
stderr は入力を標準エラー出力に出力します。debug は入力を ["DEBUG": 入力値] の形式で標準エラー出力に出力します。
$ echo '"ABC"' | jq 'debug' > /dev/null ["DEBUG:","ABC"]
入力ファイル名を返します。
$ jq 'input_filename' sample.json "sample.json"
入力中の行数を返します。
$ echo '{"foo":"FOO"} {"baa":"BAA"} {"baz":"BAZ"} ' | jq -c '[input_line_number, .]' [1,{"foo":"FOO"}] [2,{"baa":"BAA"}] [3,{"baz":"BAZ"}]
--stream オプションと同様、入力値をストリーム形式に変換します。ストリーム形式は値のひとつひとつについて、[[path], value] の形式で与えられます。[path] はキーまたは配列インデックスの配列です。[[path]] はそのパスの処理が完了したことを示します。
$ echo '{"a":{"b":123,"c":["X","Y"]}}' | jq -c 'tostream' [["a","b"],123] [["a","c",0],"X"] [["a","c",1],"Y"] [["a","c",1]] [["a","c"]] [["a"]]
ストリーム形式に変換したJSON列を引数として受け取り、変換前の形式に逆変換します。
$ echo '{"a":{"b":123,"c":["X","Y"]}}' | jq -c '[tostream] | fromstream(.[])' {"a":{"b":123,"c":["X","Y"]}}
数値を入力とし、stream_expression で与えられたストリーミング式の出力の左側から対応する数のパス要素を切り捨てます。(詳細不明...)
$ echo '["A",["B"]]' | jq -c '[tostream]' [[[0],"A"],[[1,0],"B"],[[1,0]],[[1]]] $ jq -nc '[1|truncate_stream([[0],"A"],[[1,0],"B"],[[1,0]],[[1]])]' [[[0],"B"],[[0]]] $ echo '[[[0],"B"],[[0]]]' | jq -c 'fromstream(.[])' ["B"]
ビルトインの一覧を返します。
$ jq -n 'builtins' [ "input_line_number/0", "input_filename/0", "now/0", "localtime/0", "gmtime/0", "mktime/0", :
def は関数を定義します。下記の例では半径を受け取って円の面積を求める関数 area_of_circle を定義し、それを呼び出しています。
$ echo '[10,20,30]' | jq -c ' def area_of_circle: . * . * 3.14; map(area_of_circle)' [314,1256,2826]
引数をもつ関数は下記の様に定義します。
$ echo '[10,20,30]' | jq -c ' def area_of_circle(x): x * x * 3.14; map(area_of_circle(.))' [314,1256,2826]
モジュールファイルを読み込みます。
$ cat mymodule.jq def times(n): . * n; $ echo '[10,20,30]' | jq -c 'include "mymodule"; map(times(3))' [30,60,90]
as を用いて変数を定義することができます。下記の例では users オブジェクトを $users という名前の変数に覚えておき、.emails[] 処理の中でそれを参照しています。
$ echo ' { "users": { "U001": "Yamada", "U002": "Tanaka", "U003": "Suzuki" }, "emails": [ {"user_id": "U001", "email": "yamada@example.com"}, {"user_id": "U002", "email": "tanaka@example.com"}, {"user_id": "U003", "email": "suzuki@example.com"} ] } ' | jq -c '.users as $users | .emails[] | {user: $users[.user_id], email}' {"user":"Yamada","email":"yamada@example.com"} {"user":"Tanaka","email":"tanaka@example.com"} {"user":"Suzuki","email":"suzuki@example.com"}
変数代入する際に値の型がひとつに決まらない場合、分割代替演算子を用いることができます。下記の例では、baa の値はオブジェクトだったりオブジェクト配列だったりしますが、分割代替演算子 ?// を用いて、オブジェクトの場合の変数代入と、オブジェクト配列だった場合の変数代入を記述することができます。
$ echo ' [ {"foo": {"baa": 123}}, {"foo": [{"baa": 456}]} ]' | jq -c '.[] as {foo: {$baa}} ?// {foo: [{$baa}]} | {$baa}' {"baa":123} {"baa":456}
@foo は変換処理やエスケープ処理を行います。
$ echo '123' | jq '@text' "123" $ echo '{"foo":"FOO"}' | jq '@json' "{\"foo\":\"FOO\"}" $ echo '"x > y"' | jq '@html' "x > y" $ echo '"foo?"' | jq '@uri' "foo%3F" $ echo '[123,"ABC"]' | jq '@csv' "123,\"ABC\"" $ echo '[123,"ABC"]' | jq '@tsv' "123\tABC" $ echo '"x > y"' | jq '@sh' "'x > y'" $ echo '"This is Japan."' | jq '@base64' "VGhpcyBpcyBKYXBhbi4=" $ echo '"VGhpcyBpcyBKYXBhbi4="' | jq '@base64d' "This is Japan."
最初の形式は、cond1 が真の時 exp1 を実行します。2番目の形式は、cond1 が真の時は exp1 を、さもなくば exp2 を実行します。3番目の形式は、cond1 が真であれば exp1 を、cond2 が真であれば exp2 を、さもなくば exp3 を実行します。
if cond1 then exp1 end if cond1 then exp1 else exp2 end if cond1 then exp1 elif cond2 then exp2 else exp3 end
使用例を下記に示します。
$ echo '[72,85,92]' | jq '.[] | if . > 80 then "Good!" else "Bad!" end' "Bad!" "Good!" "Good!"
exp1 実行中にエラーが発生すると処理を中断して exp2 を実行します。
try exp1 catch exp2
使用例を下記に示します。
$ echo '[1,2,3]' | jq 'try .foo catch "ERROR"' "ERROR"
exp? は try exp の省略形です。エラーが発生してもエラーを無視します。
$ echo '123' | jq '.[]' jq: error (at <stdin>:1): Cannot iterate over number (123) $ echo '123' | jq '.[]?' $
\(filter) を記述することで抽出した値を文字列の中に埋め込むことができます。
$ echo '{"name":"Tanaka"}' | jq '"My name is \(.name)."' "My name is Tanaka."
環境変数 JQ_COLORS で色をカスタマイズすることができます。最初の x;y は null の色、次の x;y は false の色、その後、true の色、数字の色、文字列の色、[] の色、{} の色が続きます。x には 1(明るい)、2(暗い)、4(アンダースコア)、5(点滅)、7(反転)、8(非表示) のいずれかを指定します。y には 30(黒)、31(赤)、32(緑)、33(黄色)、34(青)、35(マゼンタ)、36(シアン)、37(白) のいずれかを指定します。
$ export JQ_COLORS="1;30:0;37:0;37:0;37:0;32:1;33:1;33"