このドキュメントはStephen Dolan氏が権利を有するコマンドラインプロセッサーjqのマニュアルおよびチュートリアルを、CC-BY-3.0の条件に基づき日本語へ翻訳したものです。

Stephen Dolan氏は日本語版の公開や翻訳について関与するものではありません。

翻訳により混入した誤りや誤字の責任はYuji Okazawaに帰属します。

jq マニュアル (開発バージョン)

リリース済みバージョンについては次のリンクを参照してください jq 1.6 jq 1.5 jq 1.4 jq 1.3

jqは「フィルター」プログラムです。入力を受け取り出力を生成します。 受け取ったオブジェクトから任意のフィールドを抽出する多数のフィルターを内蔵しているため、数値から文字列への変換など、さまざまな標準的なタスクを実行できます。

フィルターはさまざまな方法で組み合わせることができます。 フィルターの出力を他のフィルターの入力へパイプで連結することもできますし、フィルターの出力を配列へ集めることもできます。

中には複数の結果を生成するフィルターがあります。 例えば、入力に与えた配列のそれぞれの要素を出力するようなフィルターもあるのです。 そのようなフィルターと別のフィルターをパイプで連結すると、配列のそれぞれの要素を次のフィルターへ入力するようになります。 jqは一般的なプログラミング言語が繰り返しや反復で実現している処理を、フィルターを連結するだけで実現できるのです。

どんなフィルターにも入力と出力があるのは重要なので覚えておきましょう。 文字列リテラル"hello"や数値リテラル42は、どんな入力を受け取っても常に同じリテラルを出力するフィルターなのです。 2つのフィルターを組み合わせる演算子は、加算(addition)演算子のように、基本的に同じ入力をそれぞれのフィルターに渡して、それらの結果を統合します。 平均値フィルターはadd / lengthのように実装できます。 この場合、入力された配列をaddlengthそれぞれのフィルターに渡してから、最後に除算することになります。

説明が先走りすぎたので :) もう少し簡単な例を紹介していきます。

jqの実行方法(Invoking jq)

jqフィルターはJSONデータのストリームを処理します。 jqは空白文字列を区切り文字とする JSON 値の並びとして入力を評価します。 そして、それぞれのJSON値を指定したフィルターへ渡します。 フィルターの出力は、入力と同じ空白文字列を区切り文字とするJSON値として標準出力へ書き込みます。

注意:シェルのクォート規則には注意が必要です。 基本的にjqプログラムへ指定する値は常にシングルクォート(U+0027)で囲むのがベストです。 jqが特別扱いするさまざまな文字の中にはシェルのメタ文字も含まれるからです。 具体的にはjq "foo"のように実行すると、ほとんどの Unix シェルではjq fooを実行することになり、foo is not definedというエラーになるでしょう。 Windowsのコマンドシェル(cmd.exe)で、-f 実行ファイル名のように実行するのではなく、コマンドラインからjqを実行するときは、ダブルクォート(U+0022)でベストです。 ただし、jqプログラムへ指定する値にダブルクォートを含める場合、バックスラッシュ(U+005c)でエスケープしなければなりません。

jqがどのように入力を読み取り、出力へ書き込むかはコマンドラインオプションで指定できます。

  • --version:

jqのバージョンを出力し、終了ステータス0で終了します。

  • --seq:

jqへの入力と出力をMIMEタイプスキームapplication/json-seqにより分割します。 出力するときはオブジェクトのそれぞれのフィールドを出力する前にレコードセパレータ文字(ASCII RS)を挿入し、それぞれのオブジェクトの後に改行文字(ASCII LF)を挿入します。 入力されたJSON文字列について、解析に失敗したら警告を出力し、次のレコードセパレータ文字まで読み飛ばします。 このオプションを指定した場合、--seqオプションを指定しなかったjqの出力も解析します。

  • --stream:

入力をストリームとして解釈し、パスとリーフ値(スカラー値や空配列、空オブジェクト)の配列を出力します。 例えば"a"の出力は[[],"a"]になります。 また[[],"a",["b"]]の出力は[[0,[]],[[1],"a"],[[2,0],"b"],[[2,0]],[[2]]になります。

巨大な入力を処理したいときは便利です。 フィルターにreduceおよびforeach構文を組み合わせれば、大量の入力を逐次的に集約できます。

  • --slurp/-s:

入力されたそれぞれのJSONオブジェクトへフィルターを適用する代わりに、全ての入力ストリームを大きな配列にして1度だけフィルターを適用します。

  • --raw-input/-R:

入力をJSONとして解析しません。 代わりにそれぞれの入力行を文字列としてフィルターへ渡します。 --slurpオプションと組み合わせると、全ての入力を単一の長い文字列としてフィルターへ渡すことができます。

  • --null-input/-n:

入力を読み取りません! 代わりにnullを入力としてフィルターを実行します。 簡単な計算機として使用する、あるいは、0からJSONデータを組み立てるためにjqを使うときは便利です。

  • --compact-output / -c:

jqのデフォルト出力はJSONを整形します。 このオプションを指定すると、それぞれのJSONオブジェクトを1行ずつ出力する代わりに、よりコンパクトに出力します。

  • --tab:

2文字の空白文字(U+0020)ではなくタブ(U+0009)でインデントします。

  • --indent n:

指定された数(ただし7未満)の空白文字(U+0020)でインデントします。

  • --color-output / -C and --monochrome-output / -M:

疑似端末の標準出力へ出力する場合、jqのデフォルト出力はJSONを色付けします。 -Cオプションを指定した場合、パイプやファイルへ出力する場合でも強制的に色付けします。 -Mオプションを指定した場合は色付けを無効化します。

使用する色種類は環境変数JQ_COLORSで制御できます(詳しくは後述します)。

  • --binary / -b:

WindowsユーザーがWSLやMSYS2やCygwinからネイティブ実行可能形式のjq.exeを実行するときはこのオプションを指定しなければなりません。 指定しなかった場合jqは改行文字(LF)を復帰文字と改行文字(CRLF)へ変換します。

  • --ascii-output / -a:

jqは非ASCIIのユニコードコードポイントをUTF-8として出力します。 "\u03bc"のようにエスケープシーケンスを入力した場合でも同様です。 このオプションを指定した場合、jqはASCII文字だけを出力するようになります。非ASCII文字は等価なエスケープシーケンスへ変換します。

  • --unbuffered:

JSONオブジェクトを出力するたびに出力バッファをフラッシュします。 (遅いデータソースの出力とjqをパイプで連結し、jqの出力を別の何かの入力へパイプで連結している場合は便利です)

  • --sort-keys / -S:

それぞれのオブジェクトのフィールドを文字列昇順にして出力します。

  • --raw-output / -r:

このオプションを指定した場合、結果をクォートされたJSON文字列として書式化せず文字列として標準出力へ書き込みます。 jqがJSONベースではないシステムと連携するときは便利です。

  • --join-output / -j:

-rと同様ですが、それぞれの出力の後に改行文字を挿入しません。

  • --nul-output / -0:

-rと同様ですが、それぞれの出力の後にNULを挿入します。 値として改行文字を含むような場合に便利です。

  • -f filename / --from-file filename:

コマンドラインではなくファイルからフィルターを読み込みます。 awkコマンドの-fオプションと同様です。 #で始まる行はコメントとして無視します。

  • -Ldirectory / -L directory:

モジュールを探索するディレクトリをdirectoryに指定します。 このオプションを指定した場合、組み込みの検索リストは使いません。 後述のモジュールに関するセクションを参照してください。

  • -e / --exit-status:

このオプションを指定すると、最後に出力した値がfalsenullでなければ、終了ステータスは0になります。 falsenullなら、終了ステータスは1になります。 正常に出力出来なかった場合、終了ステータスは4になります。 通常なら、オプション指定や入力に問題がある場合やシステムエラーの場合、終了ステータスは2になります。 コンパイルエラーの場合、終了ステータスは3になります。 正常終了した場合、終了ステータスは0になります。

組み込み関数のhalt_errorでも終了ステータスを設定できます。

  • --arg name value:

指定した値の変数をjqに渡します。 jqを実行するとき--arg foo barを渡すと、プログラムから$fooという変数で"bar"という値を参照できます。 valueは文字列になるので注意してください。つまり、--arg foo 123を渡した場合$fooの値は"123"になります。

名前付き引数は$ARGS.namedのように参照することもできます。

  • --argjson name JSON-text:

JSONにエンコードした値の変数をjqに渡します。 jqを実行するとき--argjson foo 123を渡すと、プログラムから$fooという変数で123という値を参照できます。

  • --slurpfile variable-name filename:

指定したファイルに含まれる全てのJSON文字列をJSON値の配列として解釈した結果を、指定した名前のグローバル変数で参照できるようにします。 jqを実行するとき--slurpfile foo barを渡すと、プログラムからは$fooという変数で配列(barというファイルに含まれる文字列)を参照できます。

  • --rawfile variable-name filename:

指定したファイルに含まれる全ての文字列を、指定した名前のグローバル変数で参照できるようにします。 jqを実行するとき--rawfile foo barを渡すと、プログラムからは$fooという変数で文字列(barというファイルに含まれる文字列)を参照できます。

  • --argfile variable-name filename:

このオプションは使わないでください。代わりに--slurpfileを使いましょう。

--slurpfileと同じようなオプションですが、ファイルに含まれる文字列が1行だけの場合はこちらのオプションを使うようにしてください。複数行の文字列は--slurpfileにより文字列の配列として参照できます)

  • --args:

指定した値を文字列配列にします。 jqプログラムからは$ARGS.positional[]で参照できます。

  • --jsonargs:

指定した値をJSON値の配列にします。 jqプログラムからは$ARGS.positional[]で参照できます。

  • --run-tests [filename]:

指定したファイルあるいは標準入力から受け取ったテストを実行します。 このオプションは最後に指定しなければなりません。また、その前に指定していたオプションによる制御は無視されます。 入力はコメント行、空行、それから1行のプログラム行に対する複数行の出力(期待値)です。 空行が終端を表します。 コンパイルの失敗を確認するテストは"%%FAIL"で開始して、失敗するプログラムを記述します。期待値には実際のエラーメッセージと比較するメッセージを記述します。

このオプションは後方互換性を損なう変更をする場合があるため注意してください。

基本的なフィルター(Basic filters)

アイデンティティ(Identity): .

.は最も単純なフィルターです。 入力を変更せずそのまま出力するという性質から、アイデンティティ(同一性)演算子と呼ばれています。

jqのデフォルト出力は全ての出力を整形します。 このフィルターはcurlなどが出力するJSON文字列を整形するのに役立つ場合があります。

Example
jq '.'
Input"Hello, world!"
Output "Hello, world!"

オブジェクト識別子インデックス(Object Identifier-Index): .foo, .foo.bar

.fooは最も単純で便利なフィルターです。 辞書や連想配列のようなJSONオブジェクトを入力すると、キーである"foo"に対応する値を生成します。キーが存在しない場合はnullを生成します。

.foo.barという形式のフィルターは.foo|.barと等価です。

この記法はキーのように単純な識別子にだけ利用できます。 使用できるのは数字以外で始まる英数字とアンダースコア(U+005f)だけで構成された識別子です。

キーに特殊文字が含まれている場合や数字で開始する場合、ダブルクォート(U+0022)で囲まなければなりません。 例:."foo$".["foo$"]

.["foo::bar"].["foo.bar"]は使用できますが.foo::barは使用できません。 .foo.bar.["foo"].["bar"]という意味になります。

Examples
jq '.foo'
Input{"foo": 42, "bar": "less interesting data"}
Output 42
jq '.foo'
Input{"notfoo": true, "alsonotfoo": false}
Output null
jq '.["foo"]'
Input{"foo": 42}
Output 42

オプショナルオブジェクト識別子インデックス(Optional Object Identifier-Index): .foo?

.fooと同様ですが、.が配列やオブジェクトでなくてもエラーを出力しません。

Examples
jq '.foo?'
Input{"foo": 42, "bar": "less interesting data"}
Output 42
jq '.foo?'
Input{"notfoo": true, "alsonotfoo": false}
Output null
jq '.["foo"]?'
Input{"foo": 42}
Output 42
jq '[.foo?]'
Input[1,2]
Output []

汎用オブジェクトインデックス(Generic Object Index): .[<string>]

オブジェクトのフィールドは.["foo"]のような記法でも参照できます。 (前述の.fooという記法は、識別子として利用可能な文字列にだけ使用できるこの記法の省略版です。)

配列インデックス(Array Index): .[2]

インデックスの値が整数の場合、.[<value>]は配列を添え字で参照できます。 配列の添え字は0から始まるので、.[2]は3番目の要素を参照することになります。

負の添え字も使用できます。-1は末尾の要素を、-2は末尾から1つ前の要素を参照します。

Examples
jq '.[0]'
Input[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]
Output {"name":"JSON", "good":true}
jq '.[2]'
Input[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]
Output null
jq '.[-2]'
Input[1,2,3]
Output 2

配列/文字列スライス(Array/String Slice): .[10:15]

スライス記法を使用すると部分配列や部分文字列を取得できます。 .[10:15]は元の配列の添え字10(以上)から15(未満)までの要素からなる長さ5の配列を返します。 負の添え字を指定した場合、配列の末尾から逆順に数えます。 添え字を指定しなかった場合、先頭あるいは末尾になります。

Examples
jq '.[2:4]'
Input["a","b","c","d","e"]
Output ["c", "d"]
jq '.[2:4]'
Input"abcdefghi"
Output "cd"
jq '.[:3]'
Input["a","b","c","d","e"]
Output ["a", "b", "c"]
jq '.[-2:]'
Input["a","b","c","d","e"]
Output ["d", "e"]

配列/オブジェクトイテレータ(Array/Object Value Iterator): .[]

配列インデックス記法.[index]で添え字を指定しなかった場合、配列の要素を全て返します。 .[][1,2,3]を入力すると、単一の配列ではなく別々の3つの数字を生成します。

この記法をオブジェクトにも指定すると、オブジェクトの全ての値を返します。

Examples
jq '.[]'
Input[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]
Output {"name":"JSON", "good":true}
{"name":"XML", "good":false}
jq '.[]'
Input[]
Output none
jq '.[]'
Input{"a": 1, "b": 1}
Output 1
1

オプショナル配列/オブジェクトイテレータ: .[]?

.[]と同様ですが、.が配列やオブジェクトでなくてもエラーを出力しません。

カンマ(Comma): ,

2つのフィルターをカンマ(U+002c)で区切ると、プログラムの入力をそれぞれのフィルターに入力し、それぞれの出力を並び順通りに連結した値ストリームを出力します。 つまり、カンマの左側の式による結果を全て出力してから、右側の式による結果を出力します。 例えば、.foo,.barと記述すると"foo"フィールドと"bar"フィールドの値を順番に出力します。

Examples
jq '.foo, .bar'
Input{"foo": 42, "bar": "something else", "baz": true}
Output 42
"something else"
jq '.user, .projects[]'
Input{"user":"stedolan", "projects": ["jq", "wikiflow"]}
Output "stedolan"
"jq"
"wikiflow"
jq '.[4,2]'
Input["a","b","c","d","e"]
Output "e"
"c"

パイプ(Pipe): |

パイプ演算子(|)は2つのフィルターを連結します。 つまり、左側のフィルターの出力を右側のフィルターの入力に連結します。 Unixシェルのパイプとほとんど同じように使うことができます。

左側のフィルターが複数の結果を生成する場合、それぞれの結果に対して右側のフィルターを実行します。 従って.[] | .fooと記述すると、入力した配列のそれぞれの要素について"foo"フィールドの値を取得します。

.a.b.cと記述するのは.a | .b | .cと記述するのと同様です。

「パイプライン」のいずれかのステージに登場する.は入力値そのものを指します。 従って.a | . | .bと記述するのは.a.bと記述するのと同様です。 中央の..aの生成した結果を表しているからです。

Example
jq '.[] | .name'
Input[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]
Output "JSON"
"XML"

括弧(Parenthesis)

開き括弧(U+0028)と閉じ括弧(U+0029)は他のプログラミング言語と同様にグループ化する演算子です。

Example
jq '(. + 2) * 5'
Input1
Output 15

型と値(Types and Values)

jqはJSONと同じデータ型に対応しています。 すなわち数値、文字列、真偽値、配列、オブジェクト(JSONでは文字列のキーだけで構成された連想配列のこと)、"null"のことです。

JavaScriptでは真偽値、null、文字列、数値は同じように記述します。 jqでも同様に、単純な値を入力として受け取り、出力として生成します。 42はjqプログラムとして正しい形式で、入力を無視して42という値を生成します。

配列構築子(Array construction): []

JSONと同様に配列を生成するときは[]と記述します。具体的には[1,2,3]のように記述します。 パイプラインを含む任意のjq式が配列の要素になります。 全てのjq式の生成した結果を集約した単一の巨大な配列を生成します。 [.foo, .bar, .baz]のように既知の要素数の配列を生成できます。 また、[.items[].name]のようにフィルターの結果を要素とする配列を生成することもできます。

カンマ演算子を理解できればjqの配列記法を別の視点で捉えることができます。 [1,2,3]という記述は組み込み記法であるカンマ区切りの配列ではありません。 結果を集約する配列構築子[]1,2,3という式に適用したことになります。 そして、3種類の異なる結果を生成するのです。

何らかのフィルターXが4個の結果を生成するなら、[X]という式は4要素の配列に対する単一の結果を生成します。

Examples
jq '[.user, .projects[]]'
Input{"user":"stedolan", "projects": ["jq", "wikiflow"]}
Output ["stedolan", "jq", "wikiflow"]
jq '[ .[] | . * 2]'
Input[1, 2, 3]
Output [2, 4, 6]

オブジェクト構築子(Object Construction): {}

JSONと同様にオブジェクト(辞書あるいは連想配列)を生成するときは{}と記述します。具体的には{"a": 42, "b": 17}のように記述します。

キーが「識別子として利用可能な文字列」ならクォートは省略できます。つまり{a:42, b:17}のように記述できます。 キーの式表現で変数を参照すると、変数の値をキーにすることができます。 キーの式表現でリテラルや識別子や変数参照以外を使用する場合、括弧で囲まなければ鳴りません。具体的には{("a"+"b"):59}のように記述します。

値には任意の式を記述できます。(ただしコロン(U+003a)を含むなど括弧で囲まなければならない場合もあります)。 それぞれの式は{}式への入力に対して適用します。(全てのフィルターに入力と出力があることを思い出しましょう)。

{foo: .bar}と記述し、{"bar":42, "baz":43}を入力した場合、JSONオブジェクト{"foo": 42}を生成します。 このフィルターを使うとオブジェクトの特定のフィールドを選択できます。 入力したオブジェクトに次のようなフィールド("user"、"title"、"id"、"content)があるとき、{user: .user, title: .title}と記述すれば"user"と"title"を抽出できます。

ありふれた使い方のため、{user, title}のように省略する記法が用意されています。

いずれかの式が複数の結果を生成する場合、複数の辞書を生成します。 次のようなオブジェクトを入力し

{"user":"stedolan","titles":["JQ Primer", "More JQ"]}

次のような式を評価すると

{user, title: .titles[]}

次のように2つの結果を生成します。

{"user":"stedolan", "title": "JQ Primer"}
{"user":"stedolan", "title": "More JQ"}

キーを括弧で囲むと式として評価することになります。 前の例と同じ入力に対して次のような式を評価すると

{(.user): .titles}

次のような結果を生成します。

{"stedolan": ["JQ Primer", "More JQ"]}

キーで変数を参照すると変数の値をキーとして使用します。 フィールドに値を指定しなければ変数の値を使用します。 次の式は

"f o o" as $foo | "b a r" as $bar | {$foo, $bar:$foo}

次のような結果を生成します。

{"f o o":"f o o","b a r":"f o o"}
Examples
jq '{user, title: .titles[]}'
Input{"user":"stedolan","titles":["JQ Primer", "More JQ"]}
Output {"user":"stedolan", "title": "JQ Primer"}
{"user":"stedolan", "title": "More JQ"}
jq '{(.user): .titles}'
Input{"user":"stedolan","titles":["JQ Primer", "More JQ"]}
Output {"stedolan": ["JQ Primer", "More JQ"]}

再帰下降演算子(Recursive Descent): ..

再帰下降型のアイデンティティ演算子.は全ての値を生成します。 組み込み関数reduce(後で説明します)を引数無しで呼び出す場合と同様です。 XPathの//演算子とよく似ています。 ただし..aという記述は動作しません。代わりに..|.aと記述してください。 また、..|.a?と記述すれば.の前に発見したすべてのオブジェクトについてキーaの値を取得します。

path(EXP)関数(後で説明します)と?演算子を組み合わせて使用するときは特に役立ちます。

Example
jq '..|.a?'
Input[[{"a":1}]]
Output 1

組み込み演算子と組み込み関数(Builtin operators and functions)

jqの演算子の中には受け取った型に応じて異なる振る舞いをするものがあります(例えば+)。 ですが、jqは暗黙的な型変換をしません。 文字列をオブジェクトに加算しようとすればエラーになるだけで結果を生成することはありません。

加算(Addition): +

加算演算子+は2つのフィルターを引数に取り、それぞれに同じ入力を提供してその結果を加算します。 データ型によって「加算」の意味は異なります。

  • 数値 の場合、通常の算術演算をします。

  • 配列 の場合、連結してより大きな配列を生成します。

  • 文字列 の場合、連結してより大きな文字列を生成します。

  • オブジェクト の場合加算とはマージのことです。 両方のオブジェクトの全てのキーと値を持つ1つのオブジェクトを生成します。 同じキーを持つ場合、+演算子の右辺に指定したオブジェクトの値で上書きします。(再帰的にマージするときは*演算子を使います)

nullはあらゆる値に加算できます。そして元の値を変更しません。

Examples
jq '.a + 1'
Input{"a": 7}
Output 8
jq '.a + .b'
Input{"a": [1,2], "b": [3,4]}
Output [1,2,3,4]
jq '.a + null'
Input{"a": 1}
Output 1
jq '.a + 1'
Input{}
Output 1
jq '{a: 1} + {b: 2} + {c: 3} + {a: 42}'
Inputnull
Output {"a": 42, "b": 2, "c": 3}

減算(Subtraction): -

通常の数値に対する算術演算と同じように、左辺の配列から右辺の配列に一致する要素を全て取り除くことができます。

Examples
jq '4 - .a'
Input{"a":3}
Output 1
jq '. - ["xml", "yaml"]'
Input["xml", "yaml", "json"]
Output ["json"]

乗算(Multiplication)、除算(division)、剰余(modulo): *, /, and %

これらの中置演算子は両側に数値を指定した場合は意図した通りに機能します。 ゼロ除算はエラーになります。また、x % yはxのyによる剰余を算出します。

文字列と数値の乗算は、数値と同じ数だけ連結した文字列を生成します。 ただし"x" * 0nullを生成します。

文字列を別の文字列で除算すると、前者の文字列を後者の文字列で分割します。

オブジェクト同士を乗算すると再帰的にマージします。 それぞれのオブジェクトに同じキーがある場合はオブジェクト同士の加算と同様に処理します。 値がオブジェクトだった場合も同じ戦略でマージします。

Examples
jq '10 / . * 3'
Input5
Output 6
jq '. / ", "'
Input"a, b,c,d, e"
Output ["a","b,c,d","e"]
jq '{"k": {"a": 1, "b": 2}} * {"k": {"a": 0,"c": 3}}'
Inputnull
Output {"k": {"a": 0, "b": 2, "c": 3}}
jq '.[] | (1 / .)?'
Input[1,0,-1]
Output 1
-1

length

組み込み関数lengthは様々なデータ型に応じた長さを出力します。

  • 文字列の長さはユニコードコードポイント数です。 (ASCII文字だけで構成したJSONをバイト列にエンコードしたときのバイト長と同じです)

  • 配列の長さは要素数です。

  • オブジェクトの長さはキー・値ペア数です。

  • nullの長さは0です。

Example
jq '.[] | length'
Input[[1,2], "string", {"a":2}, null]
Output 2
6
1
0

utf8bytelength

組み込み関数utf8bytelengthはUTF-8にエンコードした文字列のバイト長を出力します。

Example
jq 'utf8bytelength'
Input"\u03bc"
Output 2

keys, keys_unsorted

組み込み関数keysは指定したオブジェクトのキーを配列で出力します。

キーはユニコードコードポイントの順番に基づいて「アルファベット順」に並び替えます。 あらゆる言語に対する適切な順序になるとは限りません。 しかし、ロケール設定に関わらず同じキー集合を持つオブジェクトなら同じ結果を出力します。

配列を指定すると有効な添え字の配列を返します。 添え字の範囲は0から長さ-1までです。

keys_unsorted関数はkeysと同様ですが、オブジェクトを入力した場合キーを並び替えません。 おそらく登場した順序になるでしょう。

Examples
jq 'keys'
Input{"abc": 1, "abcd": 2, "Foo": 3}
Output ["Foo", "abc", "abcd"]
jq 'keys'
Input[42,3,35]
Output [0,1,2]

has(key)

組み込み関数hasは入力したオブジェクトに指定したキーがあるかどうか、または、入力した配列に指定した添え字の要素が存在するかどうかの真偽値を出力します。

$keyが配列の場合、has($key)$keykeys関数の出力した配列の部分配列であるかどうかを確かめるのと同じ結果にあります。 ただし、has関数のほうが高速です。

Examples
jq 'map(has("foo"))'
Input[{"foo": 42}, {}]
Output [true, false]
jq 'map(has(2))'
Input[[0,1], ["a","b","c"]]
Output [false, true]

in

組み込み関数inは入力したキー(配列)が引数のオブジェクトに存在するかどうか、または、入力した添え字(配列)が引数の配列に存在するかどうかの真偽値を出力します。 基本的にはhasと逆の処理をする関数です。

Examples
jq '.[] | in({"foo": 42})'
Input["foo", "bar"]
Output true
false
jq 'map(in([0,1]))'
Input[2, 0]
Output [false, true]

map(x), map_values(x)

map(x)は入力した配列それぞれの要素に任意のフィルターxを適用し、それぞれのフィルターの生成した結果を要素とする新しい配列を生成します。 例えば、map(.+1)は数値の配列それぞれの要素をインクリメントします。

同様に、map_values(x)は入力がオブジェクトならそれぞれのフィールドの値にフィルターを適用し、元の値と置き換えたオブジェクトを生成します。

map(x)という記述は[.[] | x]と等価です。実際にそのように定義されています。 また、map_values(x)も同様に.[] |= xと等価です。

Examples
jq 'map(.+1)'
Input[1,2,3]
Output [2,3,4]
jq 'map_values(.+1)'
Input{"a": 1, "b": 2, "c": 3}
Output {"a": 2, "b": 3, "c": 4}

path(path_expression)

入力.に適用したパス式の配列表現を生成します。 出力は文字列配列(オブジェクトのキー)あるいは数値配列(配列の添え字)です。

jqにおけるパス式とは.a.[]という記法のことです。 パス式には単一の要素と正確にマッチする式と、複数要素にマッチする式があります。 例えば.a.b.cは単一の要素と正確にマッチする式で、.a[].bは複数要素にマッチする式です。

path(exact_path_expression)は入力.に対応する要素が存在しなくても指定したパス式の配列表現を生成します。 入力.nullや配列やオブジェクトです。

path(pattern)は入力.にマッチしたpatternの配列表現を生成します。

パス式は通常の式と区別されないので注意してください。 例えばpath(..|select(type=="boolean"))と記述した場合、入力.に存在する全ての真偽値型の値に対するパスだけを出力します。

Examples
jq 'path(.a[0].b)'
Inputnull
Output ["a",0,"b"]
jq '[path(..)]'
Input{"a":[{"b":1}]}
Output [[],["a"],["a",0],["a",0,"b"]]

del(path_expression)

組み込み関数delは指定したパス式に対応するキーと値を入力したオブジェクトから削除します。

Examples
jq 'del(.foo)'
Input{"foo": 42, "bar": 9001, "baz": 42}
Output {"bar": 9001, "baz": 42}
jq 'del(.[1, 2])'
Input["foo", "bar", "baz"]
Output ["foo"]

getpath(PATHS)

組み込み関数getpathは入力したオブジェクトについてPATHSのそれぞれの要素にマッチした値の配列を生成します。

Examples
jq 'getpath(["a","b"])'
Inputnull
Output null
jq '[getpath(["a","b"], ["a","c"])]'
Input{"a":{"b":0, "c":1}}
Output [0, 1]

setpath(PATHS; VALUE)

組み込み関数setpathは入力したオブジェクトについてPATHSのそれぞれの要素にマッチした値をVALUEにしたオブジェクトを生成します。

Examples
jq 'setpath(["a","b"]; 1)'
Inputnull
Output {"a": {"b": 1}}
jq 'setpath(["a","b"]; 1)'
Input{"a":{"b":0}}
Output {"a": {"b": 1}}
jq 'setpath([0,"a"]; 1)'
Inputnull
Output [{"a":1}]

delpaths(PATHS)

組み込み関数delpathsは入力したオブジェクトについてPATHSのそれぞれの要素にマッチしたフィールドを削除したオブジェクトを生成します。 PATHSはパス式(文字列配列あるいは数値配列)の配列です。

Example
jq 'delpaths([["a","b"]])'
Input{"a":{"b":1},"x":{"y":2}}
Output {"a":{},"x":{"y":2}}

to_entries, from_entries, with_entries

これらの組み込み関数はオブジェクトとキーと値からなる配列を相互に変換します。 to_entriesにオブジェクトを入力すると、キーと値k: vのオブジェクトを要素とする配列[{"key": k, "value": v}]を生成します。

from_entriesto_entriesと逆の変換をします。 with_entries(foo)to_entries | map(foo) | from_entriesの省略記法です。 オブジェクトの全てのキーと値に何らかの処理をしたい場合に便利です。 from_entriesはキーのキー名として key Key name Name を受け付けます。 また、値のキー名として value Value を受け付けます。

Examples
jq 'to_entries'
Input{"a": 1, "b": 2}
Output [{"key":"a", "value":1}, {"key":"b", "value":2}]
jq 'from_entries'
Input[{"key":"a", "value":1}, {"key":"b", "value":2}]
Output {"a": 1, "b": 2}
jq 'with_entries(.key |= "KEY_" + .)'
Input{"a": 1, "b": 2}
Output {"KEY_a": 1, "KEY_b": 2}

select(boolean_expression)

組み込み関数select(foo)は式fooが入力に対して真を返したら、入力を変更せずに出力します。それ以外の場合は何も出力しません。

リストからいずれかの要素を抽出するのに便利です。 例えば[1,2,3] | map(select(. >= 2))と記述すると[2,3]を出力します。

Examples
jq 'map(select(. >= 2))'
Input[1,5,3,0,7]
Output [5,3,7]
jq '.[] | select(.id == "second")'
Input[{"id": "first", "val": 1}, {"id": "second", "val": 2}]
Output {"id": "second", "val": 2}

arrays, objects, iterables, booleans, numbers, normals, finites, strings, nulls, values, scalars

これらの組み込み関数は、関数名に対応するデータ型のオブジェクトを抽出します。

Example
jq '.[]|numbers'
Input[[],{},1,"foo",null,true,false]
Output 1

empty

組み込み関数emptyは何も結果を生成しません。nullですらありません。

時には役に立つ場合があります。必要な時になれば分かるはずです :)

Examples
jq '1, empty, 2'
Inputnull
Output 1
2
jq '[1,2,empty,3]'
Inputnull
Output [1,2,3]

error(message)

組み込み関数errorはエラーを生成します。 nullやオブジェクト以外の入力に.aのような式を適用した場合とは違って、指定した文字列が値になります。 エラーは後述するtry/catchで処理できます。

halt

それ以上何も出力せずにjqプログラムを停止します。 終了ステータスは0になります。

halt_error, halt_error(exit_code)

それ以上何も出力せずにjqプログラムを停止します。 入力は素の文字列として修飾せずに標準エラーstderrへ出力します(文字列をダブルクォートで囲んだりしません)。 改行文字もそのままです。

引数のexit_codeはjqの終了ステータスになります。未指定の場合5です。

具体的には"Error: somthing went wrong\n"|halt_error(1)のように記述します。

$__loc__

キー"file"に対してファイル名を、キー"line"に対して$__loc__が登場した位置の行番号を値として持つオブジェクトを生成します。

Example
jq 'try error("\($__loc__)") catch .'
Inputnull
Output "{\"file\":\"<top-level>\",\"line\":1}"

paths, paths(node_filter), leaf_paths

組み込み関数pathsは入力されたオブジェクトあるいは配列の全ての要素に対応するパスを出力します。 (ただし空の配列や入力.自体は除外します)

paths(f)はフィルターfが真になる全ての値に対応するパスを出力します。 つまり、paths(numbers)と記述すると全ての数値に対応するパスを出力します。

leaf_pathspaths(scalars)の省略記法ですが、廃止予定であり、将来のメジャーリリースで削除される予定です。

Examples
jq '[paths]'
Input[1,[[],{"a":2}]]
Output [[0],[1],[1,0],[1,1],[1,1,"a"]]
jq '[paths(scalars)]'
Input[1,[[],{"a":2}]]
Output [[0],[1,1,"a"]]

add

入力した配列の全ての要素を加算した値を出力します。 要素のデータ型に応じて数値の総和や連結した文字列やマージしたオブジェクトを生成します。 データ型と処理の関係は前述した+演算子と同様です。

入力が空配列だった場合nullを出力します。

Examples
jq 'add'
Input["a","b","c"]
Output "abc"
jq 'add'
Input[1, 2, 3]
Output 6
jq 'add'
Input[]
Output null

any, any(condition), any(generator; condition)

入力した真偽値の配列について1つでもtrueがあればtrueを出力します。

入力が空配列だった場合falseを出力します。

any(condition)と記述すると、入力した配列の全ての要素を評価します。

any(generator; condition)と記述すると、指定したジェネレータの生成した全ての値を評価します。

Examples
jq 'any'
Input[true, false]
Output true
jq 'any'
Input[false, false]
Output false
jq 'any'
Input[]
Output false

all, all(condition), all(generator; condition)

入力した真偽値の配列について全ての要素がtrueだったらtrueを出力します。

all(condition)と記述すると、入力した配列の全ての要素を評価します。

all(generator; condition)と記述すると、指定したジェネレータの生成した全ての値を評価します。

入力が空配列だった場合trueを出力します。

Examples
jq 'all'
Input[true, false]
Output false
jq 'all'
Input[true, true]
Output true
jq 'all'
Input[]
Output true

flatten, flatten(depth)

入力した配列を要素とする配列について、それぞれの要素を再帰的に展開した全ての要素で置換した平坦な配列を生成します。 引数にネストの深さを指定できます。

例えば、flatten(2)と記述すると2段階のネストまで再帰します。

Examples
jq 'flatten'
Input[1, [2], [[3]]]
Output [1, 2, 3]
jq 'flatten(1)'
Input[1, [2], [[3]]]
Output [1, 2, [3]]
jq 'flatten'
Input[[]]
Output []
jq 'flatten'
Input[{"foo": "bar"}, [{"foo": "baz"}]]
Output [{"foo": "bar"}, {"foo": "baz"}]

range(upto), range(from;upto) range(from;upto;by)

組み込み関数rangeは数値の区間を生成します。 range(4;10)と記述すると4以上10未満の6つの数値を生成します。 出力する数値は別々ですが[range(4;10)]とすれば区間の配列を生成できます。

1引数で呼び出した場合、0から指定した数値まで1ずつ増分した区間を生成します。

2引数で呼び出した場合、fromからuptoまで1ずつ増分した区間を生成します。

3引数で呼び出した場合、fromからuptoまでbyずつ増分した区間を生成します。

Examples
jq 'range(2;4)'
Inputnull
Output 2
3
jq '[range(2;4)]'
Inputnull
Output [2,3]
jq '[range(4)]'
Inputnull
Output [0,1,2,3]
jq '[range(0;10;3)]'
Inputnull
Output [0,3,6,9]
jq '[range(0;10;-1)]'
Inputnull
Output []
jq '[range(0;-5;-1)]'
Inputnull
Output [0,-1,-2,-3,-4]

floor

入力した数値に最も近いより小さい整数を出力します。

Example
jq 'floor'
Input3.14159
Output 3

sqrt

入力した数値の平方根を出力します。

Example
jq 'sqrt'
Input9
Output 3

tonumber

入力を数値として解釈します。 正確な書式で記述した文字列を対応する数値へ変換します。 入力に数値以外の文字がある場合エラーを生成します。

Example
jq '.[] | tonumber'
Input[1, "1"]
Output 1
1

tostring

入力を文字列として解釈します。 入力が文字列ならそのまま出力します。 それ以外の場合はJSONエンコードします。

Example
jq '.[] | tostring'
Input[1, "1", [1]]
Output "1"
"1"
"[1]"

type

引数のデータ型を文字列で出力します。 null、真偽値boolean、数値number、文字列string、配列array、オブジェクトobjectのいずれかになります。

Example
jq 'map(type)'
Input[0, false, [], {}, null, "hello"]
Output ["number", "boolean", "array", "object", "null", "string"]

infinite, nan, isinfinite, isnan, isfinite, isnormal

算術演算には無限大やNaN(非数値、"not a number")を受け付けるものがあります。 組み込み関数isinfiniteは入力が無限大のとき真を返します。 組み込み関数isnanは入力がNaNのとき真を返します。 組み込み関数infiniteは正の無限大を返します。 組み込み関数nanはNaNを返します。 組み込み関数isnormalは入力が通常の数値なら真を返します。

0除算はエラーになるため注意してください。

今のところほとんどの算術演算は無限大やNaN、通常の数値の部分集合に対してエラーを生成しません。

Examples
jq '.[] | (infinite * .) < 0'
Input[-1, 1]
Output true
false
jq 'infinite, nan | type'
Inputnull
Output "number"
"number"

sort, sort_by(path_expression)

入力した配列の要素を並び替えた配列を生成します。 値は次の順番で並び替えます。

  • null
  • false
  • true
  • 数値
  • 文字列(アルファベット順、つまりユニコードコードポイントの昇順です)
  • 配列(記述した順に要素を評価します)
  • オブジェクト

オブジェクトの並び替え規則は少し複雑です。 まずキーの配列を並び替えた状態で比較します。 それから一致するキーについて値を比較します。

オブジェクトの特定のフィールドだけを並び替えることもできますし、任意のフィルターを適用した結果で並び替えることもできます。

sort_by(foo)と記述すると、比較しているそれぞれの要素にフィルターfooを適用した結果を比較します。

Examples
jq 'sort'
Input[8,3,null,6]
Output [null,3,6,8]
jq 'sort_by(.foo)'
Input[{"foo":4, "bar":10}, {"foo":3, "bar":100}, {"foo":2, "bar":1}]
Output [{"foo":2, "bar":1}, {"foo":3, "bar":100}, {"foo":4, "bar":10}]

group_by(path_expression)

group_by(.foo)と記述すると、入力した配列についてフィールド.fooが同じ値を持つ要素の配列を要素とする配列を生成します。 要素の並び順はフィールド.fooの値になります。

.fooのようなフィールドアクセスだけでなく、任意のjq式を指定できます。 並び順はsortと同じ規則です。

Example
jq 'group_by(.foo)'
Input[{"foo":1, "bar":10}, {"foo":3, "bar":100}, {"foo":1, "bar":1}]
Output [[{"foo":1, "bar":10}, {"foo":1, "bar":1}], [{"foo":3, "bar":100}]]

min, max, min_by(path_exp), max_by(path_exp)

入力した配列から最小値あるいは最大値を探索します。

min_by(path_exp)max_by(path_exp)と記述すると、パス式path_expで指定したフィールドあるいはプロパティを探索します。 例えばmin_by(.foo)と記述するとフィールドfooが最小値のオブジェクトを探索します。

Examples
jq 'min'
Input[5,4,2,7]
Output 2
jq 'max_by(.foo)'
Input[{"foo":1, "bar":14}, {"foo":2, "bar":3}]
Output {"foo":2, "bar":3}

unique, unique_by(path_exp)

入力した配列の重複を除去して並び替えた配列を生成します。

unique_by(path_exp)と記述すると、それぞれの要素について引数のパス式path_expで指定したフィールドの値だけを参照します。 group_byの生成した配列から1要素だけ取り出して配列を生成することもできます。

Examples
jq 'unique'
Input[1,2,5,3,5,3,1,3]
Output [1,2,3,5]
jq 'unique_by(.foo)'
Input[{"foo": 1, "bar": 2}, {"foo": 1, "bar": 3}, {"foo": 4, "bar": 5}]
Output [{"foo": 1, "bar": 2}, {"foo": 4, "bar": 5}]
jq 'unique_by(length)'
Input["chunky", "bacon", "kitten", "cicada", "asparagus"]
Output ["bacon", "chunky", "asparagus"]

reverse

入力した配列を逆順にした配列を生成します。

Example
jq 'reverse'
Input[1,2,3,4]
Output [4,3,2,1]

contains(element)

contains(b)と記述すると、入力に値bと完全に一致する要素があれば真を返します。 文字列Bが文字列Aの部分文字列であるとき、文字列Aは文字列Bを含むことになります。 配列Bが配列Aの部分配列であるとき、配列Aは配列Bを含むことになります。 オブジェクトBのフィールドがオブジェクトAのフィールドの部分集合であるとき、オブジェクトAはオブジェクトBを含むことになります。 他のデータ型については値が等しければお互いを含むことになります。

Examples
jq 'contains("bar")'
Input"foobar"
Output true
jq 'contains(["baz", "bar"])'
Input["foobar", "foobaz", "blarp"]
Output true
jq 'contains(["bazzzzz", "bar"])'
Input["foobar", "foobaz", "blarp"]
Output false
jq 'contains({foo: 12, bar: [{barp: 12}]})'
Input{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}
Output true
jq 'contains({foo: 12, bar: [{barp: 15}]})'
Input{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}
Output false

indices(s)

入力.に存在する引数sの位置からなる配列を生成します。 入力が配列でsも配列なら、配列としてsに一致する全ての部分配列の位置からなる配列を生成します。

Examples
jq 'indices(", ")'
Input"a,b, cd, efg, hijk"
Output [3,7,12]
jq 'indices(1)'
Input[0,1,2,1,3,1,4]
Output [1,3,5]
jq 'indices([1,2])'
Input[0,1,2,3,1,4,2,5,1,2,6,7]
Output [1,8]

index(s), rindex(s)

index(s)と記述した場合、入力.に存在する引数sの最初の位置を生成します。 rindex(s)と記述した場合、入力.に存在する引数sの最後の位置を生成します。

Examples
jq 'index(", ")'
Input"a,b, cd, efg, hijk"
Output 3
jq 'rindex(", ")'
Input"a,b, cd, efg, hijk"
Output 12

inside

組み込みフィルターinside(b)は、入力がbに内包されるなら真を返します。 本質的にはcontainsの逆バージョンです。

Examples
jq 'inside("foobar")'
Input"bar"
Output true
jq 'inside(["foobar", "foobaz", "blarp"])'
Input["baz", "bar"]
Output true
jq 'inside(["foobar", "foobaz", "blarp"])'
Input["bazzzzz", "bar"]
Output false
jq 'inside({"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]})'
Input{"foo": 12, "bar": [{"barp": 12}]}
Output true
jq 'inside({"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]})'
Input{"foo": 12, "bar": [{"barp": 15}]}
Output false

startswith(str)

入力.が指定された文字列で開始するなら真を返します。

Example
jq '[.[]|startswith("foo")]'
Input["fo", "foo", "barfoo", "foobar", "barfoob"]
Output [false, true, false, true, false]

endswith(str)

入力.が指定された文字列で終了するなら真を返します。

Example
jq '[.[]|endswith("foo")]'
Input["foobar", "barfoo"]
Output [false, true]

combinations, combinations(n)

入力した配列について、全ての要素の組み合わせからなる配列を生成します。 引数nは、入力した配列の要素が出力する配列に登場する回数です。

Examples
jq 'combinations'
Input[[1,2], [3, 4]]
Output [1, 3]
[1, 4]
[2, 3]
[2, 4]
jq 'combinations(2)'
Input[0, 1]
Output [0, 0]
[0, 1]
[1, 0]
[1, 1]

ltrimstr(str)

入力.が指定された文字列で開始するなら、引数の文字列を除去した文字列を生成します。

Example
jq '[.[]|ltrimstr("foo")]'
Input["fo", "foo", "barfoo", "foobar", "afoo"]
Output ["fo","","barfoo","bar","afoo"]

rtrimstr(str)

入力.が指定された文字列で終了するなら、引数の文字列を除去した文字列を生成します。

Example
jq '[.[]|rtrimstr("foo")]'
Input["fo", "foo", "barfoo", "foobar", "foob"]
Output ["fo","","bar","foobar","foob"]

explode

入力した文字列を、それぞれの文字に対応するユニコードコードポイントの数値にした配列を生成します。

Example
jq 'explode'
Input"foobar"
Output [102,111,111,98,97,114]

implode

explodeと逆に、入力した配列の要素であるユニコードコードポイントに対応する文字を連結した文字列を生成します。

Example
jq 'implode'
Input[65, 66, 67]
Output "ABC"

split(str)

入力した文字列を、引数の文字列で分割した配列を生成します。

Example
jq 'split(", ")'
Input"a, b,c,d, e, "
Output ["a","b,c,d","e",""]

join(str)

引数の文字列を区切り文字として、入力した配列の要素を連結した文字列を生成します。 組み込み関数splitの逆バージョンです。 つまり、split("foo") | join("foo")と記述すると、入力した文字列と同じ文字列を出力します。

入力した数値や真偽値は文字列へ変換します。 nullは空文字列として扱います。 配列やオブジェクトには対応していません。

Examples
jq 'join(", ")'
Input["a","b,c,d","e"]
Output "a, b,c,d, e"
jq 'join(" ")'
Input["a",1,2.3,true,null,false]
Output "a 1 2.3 true false"

ascii_downcase, ascii_upcase

組み込み関数ascii_downcaseは、入力した文字列のアルファベット(aからzあるいはA-Z)を小文字に変換した文字列を生成します。 組み込み関数ascii_upcaseは、入力した文字列のアルファベット(aからzあるいはA-Z)を大文字に変換した文字列を生成します。

while(cond; update)

組み込み関数while(cond; update)は条件condが偽になる間、入力.に繰り返しupdateを適用します。

jqの内部では再帰関数として定義されているので注意してください。 whileの再帰的な呼び出しは、updateが入力に対して多くても1つだけ出力を生成するなら追加のメモリを消費しません。 詳しくは高度な使い方のセクションで説明します。

Example
jq '[while(.<100; .*2)]'
Input1
Output [1,2,4,8,16,32,64]

until(cond; next)

組み込み関数until(cond; next)は条件condが真になる間、入力.に繰り返しnextを適用します。

jqの内部では再帰関数として定義されているので注意してください。 untilの再帰的な呼び出しは、nextが入力に対して多くても1つだけ出力を生成するなら追加のメモリを消費しません。 詳しくは高度な使い方のセクションで説明します。

Example
jq '[.,1]|until(.[0] < 1; [.[0] - 1, .[1] * .[0]])|.[1]'
Input4
Output 24

recurse(f), recurse, recurse(f; condition), recurse_down

組み込み関数recurse(f)を使うと再帰的なデータ構造を探索し、あらゆる段階のデータを抽出できます。 次のようにファイルシステムの情報を入力した場合を考えてみましょう。

{"name": "/", "children": [
  {"name": "/bin", "children": [
    {"name": "/bin/ls", "children": []},
    {"name": "/bin/sh", "children": []}]},
  {"name": "/home", "children": [
    {"name": "/home/stephen", "children": [
      {"name": "/home/stephen/jq", "children": []}]}]}]}

ここでは全てのファイル名を抽出することにします。 つまり.name.children[].nameだけでなく、.children[].children[].nameのようにどんどん繰り返さなければいけません。 次のように記述すると実現できます。

recurse(.children[]) | .name

引数を指定しない場合、recurse(.[]?)と同じ意味になります。

recurse(f)recurse(f; . != null)と同一です。 再帰の深さを気にせず実行できます。

recurse(f; condition)はジェネレーターです。 conditionが真になるまで入力.を繰り返しfに適用します。 つまり.|f, .|f|f, .|f|f|fのような繰り返しになります。 例えば、理屈ではrecurse(.+1; true)のように記述すれば全ての整数を出力できます。

recurse_downは互換性を保つために残っている引数無しのrecurseの別名です。 廃止予定であり、将来のメジャーリリースで削除される予定です。

recurse(f)による再帰呼び出しは、fが入力に対して多くても1つだけ出力を生成するなら追加のメモリを消費しません。

Examples
jq 'recurse(.foo[])'
Input{"foo":[{"foo": []}, {"foo":[{"foo":[]}]}]}
Output {"foo":[{"foo":[]},{"foo":[{"foo":[]}]}]}
{"foo":[]}
{"foo":[{"foo":[]}]}
{"foo":[]}
jq 'recurse'
Input{"a":0,"b":[1]}
Output {"a":0,"b":[1]}
0
[1]
1
jq 'recurse(. * .; . < 20)'
Input2
Output 2
4
16

walk(f)

組み込み関数walk(f)は入力されたエンティティの全ての要素へ再帰的にフィルターfを適用します。 要素が配列だったら、最初に全ての配列要素へfを適用してから、配列全体を対象にfを適用します。 要素がオブジェクトだったら、最初に全てのフィールドへfを適用してから、オブジェクト全体を対象にfを適用します。 実際には、具体例のように入力をテストするフィルターを指定することになるでしょう。 1つ目の例は、配列の前に配列の要素である配列を処理することの利点を示しています。 2つ目の例は、入力に含まれる全てのオブジェクトの全てのキーについて変更できるかどうかを確かめています。

Examples
jq 'walk(if type == "array" then sort else . end)'
Input[[4, 1, 7], [8, 5, 2], [3, 6, 9]]
Output [[1,4,7],[2,5,8],[3,6,9]]
jq 'walk( if type == "object" then with_entries( .key |= sub( "^_+"; "") ) else . end )'
Input[ { "_a": { "__b": 2 } } ]
Output [{"a":{"b":2}}]

$ENV, env

組み込み変数$ENVはjqコマンドを実行した時点の環境変数を表すオブジェクトです。

組み込み関数envは実行中のjqプロセスの環境変数を出力します。

現時点で環境変数を設定する機能はありません。

Examples
jq '$ENV.PAGER'
Inputnull
Output "less"
jq 'env.PAGER'
Inputnull
Output "less"

transpose

配列の配列のようにでこぼこした表を転置します。 不足している行の値にはnullを追加するため、結果は常に正方行列になります。

Example
jq 'transpose'
Input[[1], [2,3]]
Output [[1,2],[null,3]]

bsearch(x)

組み込み関数bsearch(x)は入力された配列についてxを軸とする2分探索を実行します。 入力の配列が並び替えた状態でxを含むなら、配列中に登場したxの添え字を返します。 並び替えた状態だけどxを含まないなら、(-1 - ix)を返します。 ixxを挿入する位置なので、(-1 - ix)は配列の並び順を保ちつつxを挿入した後のxの添え字になります。 配列が並び替えた状態でないとしてもbsearch(x)は整数を返しますが、おそらく意味の無い値です。

Examples
jq 'bsearch(0)'
Input[0,1]
Output 0
jq 'bsearch(0)'
Input[1,2,3]
Output -1
jq 'bsearch(4) as $ix | if $ix < 0 then .[-(1+$ix)] = 4 else . end'
Input[1,2,3]
Output [1,2,3,4]

文字列の内挿 - \(foo)

文字列の中にバックスラッシュ(U+005c)と括弧で式を埋め込むことができます。 式の結果は文字列として挿入されます。

Example
jq '"The input was \(.), which is one less than \(.+1)"'
Input42
Output "The input was 42, which is one less than 43"

tojson, fromjson

組み込み関数tojsonは入力された値をJSON文字列として出力します。 逆に、組み込み関数fromjsonは入力された値をJSON文字列として解釈します。 組み込み関数tostringは文字列を変更せずに出力しますが、tojsonは文字列をJSON文字列へエンコードして出力します。

Examples
jq '[.[]|tostring]'
Input[1, "foo", ["foo"]]
Output ["1","foo","[\"foo\"]"]
jq '[.[]|tojson]'
Input[1, "foo", ["foo"]]
Output ["1","\"foo\"","[\"foo\"]"]
jq '[.[]|tojson|fromjson]'
Input[1, "foo", ["foo"]]
Output [1,"foo",["foo"]]

文字列の書式化とエスケープ

文字列の書式化やエスケープには@fooという記法を利用します。 URLを組み立てたり、HTMLやXMLなどのドキュメントを生成したりする場合に役立ちます。 @fooはフィルターとしても利用できます。 エスケープのために利用できる記法は次のとおりです。

  • @text:

組み込み関数tostringを呼び出します。詳しくは関数の説明を参照してください。

  • @json:

入力をJSONにシリアライズします。

  • @html:

HTML/XMLエスケープを行います。 つまり、<>%'"という文字列はそれぞれ&lt;&gt;&amp;&apos;&quot;へエスケープします。

  • @uri:

パーセントエンコーディングします。 つまり、URIの予約文字を%XXへエスケープします。

  • @csv:

入力は配列でなければなりません。 出力はCSVです。 文字列はダブルクォートで囲みますし、文字列中のダブルクォートは二重のダブルクォートへエスケープします。

  • @tsv:

入力は配列でなければなりません。 出力はTSV(タブ区切り)です。 入力した配列の要素は単一の行として出力します。 フィールドの区切り文字はタブ文字(U+0009)です。 入力に含まれる改行文字(U+000a)や復帰文字(U+000d)、タブ文字(U+0009)やバックスラッシュ(U+005c)は、それぞれ対応するエスケープ文字の\n\r\t\\へエスケープします。

  • @sh:

入力をPOSIXシェルのコマンドラインで利用できる形式へエスケープします。 配列を入力した場合、空白文字で区切られた文字列の系列を出力します。

  • @base64:

入力をRFC4648で定義されたBASE64符号へ変換します。

  • @base64d:

@base64とは反対に、入力をRFC4648で定義されたBASE64符号として復号します。 (注意点:復号した文字列の文字エンコーディングがUTF-8でない場合の結果は未定義です)

これらの記法は文字列の内挿と組み合わせて便利に使うことができます。 トークン@fooに続けてリテラル文字列を記述できるということです。 リテラル文字列はエスケープしません。 ただし、リテラル文字列に内挿された式の結果はエスケープされます。 例えば次のように記述して

@uri "https://www.google.com/search?q=\(.search)"

{"search":"what is jq?"}を入力すると、次のように出力します。

"https://www.google.com/search?q=what%20is%20jq%3F"

スラッシュ(U+002f)やクエスチョン(U+003f)など、リテラル文字列のURLに含まれる文字はエスケープされないことに注意してください。

Examples
jq '@html'
Input"This works if x < y"
Output "This works if x &lt; y"
jq '@sh "echo \(.)"'
Input"O'Hara's Ale"
Output "echo 'O'\\''Hara'\\''s Ale'"
jq '@base64'
Input"This is a message"
Output "VGhpcyBpcyBhIG1lc3NhZ2U="
jq '@base64d'
Input"VGhpcyBpcyBhIG1lc3NhZ2U="
Output "This is a message"

日時関数

jqは日時を扱う基本的な機能を高水準関数と低水準関数の組み込み関数として提供します。 どの関数もたいてい時刻はUTCとして扱います。

組み込み関数fromdateiso8601はISO 8601形式の日時を解析して、UNIXエポック(1970-01-01T00:00:00Z)からの秒数(数値)を出力します。 組み込み関数todateiso8601はその逆の変換をします。

組み込み関数fromdateは日時文字列を解析します。 現時点ではISO 8601形式にのみ対応していますが、将来的には他の形式にも対応する予定です。

組み込み関数todatetodateiso8601の別名です。

組み込み関数nowは現在日時のUNIXエポック秒を出力します。

jqはCライブラリの時刻関数(strptimestrftimestrflocaltimemktimegmtimelocaltime)を呼び出す低水準インターフェイスも提供しています。 strptimestrftimeの書式文字についてはホストOSのドキュメントを参照してください。 (注意点:特に地域化の機能など、jqとして安定したインターフェイスを提供する必然性はありません)

組み込み関数gmtimeはUNIXエポック秒を入力すると、グリニッジ標準時へ換算した要素別の日時からなる配列を出力します(順番は年、月(0から数えます)、月の日、時、分、秒、週の日、年の日)。 月以外は1から数えた数値になります。 システムによっては1900年3月1日より以前の日時を入力すると、間違った週の日が出力される場合があります。 2099年12月31日以降の日時についても同様です。

組み込み関数localtimegmtimeと同様の機能ですが、タイムゾーンの設定に従います。

組み込み関数mktimeには、gmtimestrptimeの生成する要素別の日時を入力します。

組み込み関数strptime(fmt)は引数の書式文字列fmtにマッチする文字列を解釈します。 出力はgmtimeと同様に要素別の日時からなる配列で、mktimeの入力に利用できます。

組み込み関数strftime(fmt)は入力された日時(GMT)を引数の書式文字列fmtで書式化します。 組み込み関数strflocaltimeも同様の機能ですが、タイムゾーンの設定に従います。

strptimeおよびstrftimeの書式文字列は、ほとんどのCライブラリドキュメントで説明されています。 ISO 8601形式の日時は"%Y-%m-%dT%H:%M:%SZ"と記述します。

jqはシステムの提供する全ての日時機能に対応しているわけではありません。 特にmacOSではstrptime(fmt)へ指定できる書式文字列の%u%jは未対応です。

Examples
jq 'fromdate'
Input"2015-03-05T23:51:47Z"
Output 1425599507
jq 'strptime("%Y-%m-%dT%H:%M:%SZ")'
Input"2015-03-05T23:51:47Z"
Output [2015,2,5,23,51,47,4,63]
jq 'strptime("%Y-%m-%dT%H:%M:%SZ")|mktime'
Input"2015-03-05T23:51:47Z"
Output 1425599507

SQLスタイル演算子

jqはいくつかSQLスタイルの演算子を提供します。

  • INDEX(stream; index_expression):

組み込み演算子INDEX(stream; expr)はオブジェクトを生成します。 キーはstreamに式exprを適用した結果、値はstreamです。

  • JOIN($idx; stream; idx_expr; join_expr):

組み込み演算子JOIN($idx; stream; idx_expr; join_expr)streamの値を$idxに結合します。 インデックスのキーはstreamに式idx_exprを適用した結果、値はstreamです。 ストリームの要素が配列ならインデックスの対応する値と共に式join_exprを評価し、結果を生成します。

  • JOIN($idx; stream; idx_expr):

JOIN($idx; stream; idx_expr; .)と同様です。

  • JOIN($idx; idx_expr):

JOIN($idx; .; idx_expr; .)と同様です。 結合演算について詳しくは後述します。

  • IN(s):

組み込み演算子IN(s)は入力.のいずれかの要素がストリームsに存在するときtrueを出力します。 それ以外ではfalseを出力します。

  • IN(source; s):

組み込み演算子IN(s)はストリームsourceのいずれかの要素がストリームsに存在するときtrueを出力します。 それ以外ではfalseを出力します。

builtins

全ての組み込み関数の一覧を関数名/アリティという書式で出力します。 同じ名前でもアリティの異なる関数は別の関数です。 従ってall/0all/1all/2のように出力されます。

条件演算子と比較演算子(Conditionals and Comparisions)

==, !=

a == bという式はabが等しければtrueを生成します(JSONドキュメントとして等しい場合です)。 それ以外の場合はfalseを生成します。 なお、文字列は決して数値と等しくなりません。 jqにおける==はJavascriptの===のように考えることができます。 つまり、同じデータ型で同じ値の場合等しいことになるのです。

!=は「等しい」の否定です。 従ってa != ba == bの反対の値になります。

Example
jq '.[] == 1'
Input[1, 1.0, "1", "banana"]
Output true
true
false
false

if-then-else

if A then B else C endと記述すると、Afalseあるいはnull以外を生成した場合はBになります。それ以外の場合はCになります。

if A then B endと記述した場合はif A then B else . endと記述した場合と同じ意味になります。 else節は必須ではなく、存在しない場合は.を指定した場合と同じになります。

falsenullを確かめたいというのは「真であって欲しい」という希望の表れであり、JavascriptやPythonよりもそのように考える場合が多いと思います。 ですが、そのためには希望する条件をより明示的に記述しなければならないのです。 したがってif .name then A else B endと記述しても文字列が空かどうか確かめることはできません。 他の方法が必要です。

条件Aが複数の結果を生成する場合、falsenullでないそれぞれの要素についてBを評価し、falsenullのそれぞれの要素についてCを評価します。

ifをたくさん記述しなければならない場合はelif A then Bのように記述することもできます。

Example
jq 'if . == 0 then "zero" elif . == 1 then "one" else "many" end'
Input2
Output "many"

>, >=, <=, <

比較演算子>は左辺値が右辺値を超えるかどうか、>=は左辺値が右辺値以上かどうか、<=は左辺値が右辺値以下かどうか、<は左辺値が右辺値未満かどうかを返します。

大小の基準はsortと同様です。

Example
jq '. < 5'
Input2
Output true

and/or/not

jqは論理演算子and/or/notに対応しています。 標準的な解釈と同様に、式の結果がfalsenullなら「偽」、それ以外は「真」になります。

いずれかのオペランドが複数の結果を生成するなら、論理演算子はオペランドをそれそれの値に置き換えた場合の結果を生成します。

組み込み関数notは演算子ではありません。 特殊構文ではなく、フィルターとしてパイプのさまざまな場面で呼び出すことができます。 例えば.foo and .bar | notのように記述できるのです。

論理演算子は「真」あるいは「偽」だけを生成します。 従って、PerlやPythonやRubyで一般的なイディオムvalue_that_may_be_null or defaultのような記述はできないため、純粋に論理式として使用することになります。 orを条件として評価するのではなくイディオム風に使いたければ代わりに//演算子を使うといいでしょう。

Examples
jq '42 and "a string"'
Inputnull
Output true
jq '(true, false) or false'
Inputnull
Output true
false
jq '(true, true) and (true, false)'
Inputnull
Output true
false
true
false
jq '[true, false | not]'
Inputnull
Output [false, true]

代替演算子: //

フィルターをa // bと記述すると、afalsenull以外を生成する場合はaと同じ結果を、それ以外の場合はbと同じ結果を生成します。

この演算子を使うと簡単に初期値を提供できるようになります。 .foo // 1と記述すると、.fooという要素がなければ1になるのです。 Pythonなどのプログラミング言語でorを使うイディオムと同じような効果があります。 (jqはor演算子を厳密な論理演算子として扱います)

Examples
jq '.foo // 42'
Input{"foo": 19}
Output 19
jq '.foo // 42'
Input{}
Output 42

try-catch

try exp1 catch exp2と記述すると、exp1を評価したときに発生するエラーを捕捉できます。 exp1が失敗したらそのエラーメッセージを入力としてexp2を実行するのです。 exp1が何らかの結果を生成した場合でも、例外ハンドラexp2を実行した場合はその結果も出力します。

try EXPと記述した場合の例外ハンドラはemptyです。

Examples
jq 'try .a catch ". is not an object"'
Inputtrue
Output ". is not an object"
jq '[.[]|try .a]'
Input[{}, true, {"a":1}]
Output [null, 1]
jq 'try error("some exception") catch .'
Inputtrue
Output "some exception"

制御構造からの脱出

try/catch記法はreduceforeachwhileなどの制御構造から脱出するために利用できます。

例えば次のように記述できます。

# 式`exp`が`"break"`をレイズするまで繰り返し評価します。
# `"break"`をレイズしたら、それ以上エラーをレイズしないで繰り返しを終了します。
# ただし、レイズしたエラーが`"break"`でなければ再びレイズします。
try repeat(exp) catch .=="break" then empty else error;

jqは"break""go (back) to"の宛先に指定できる名前付きラベル記法に対応しています。

label $out | ... break $out ...

break $label_nameと記述すると、式の左側を見て最も近いlabel $label_nameへ移動し、emptyを生成します。

breaklabelの関係はレキシカルスコープで決定されます。 つまり、labelbreakから「見える」ところに定義しなければなりません。

reduceから脱出するには次のように記述します。

label $out | reduce .[] as $item (null; if .==false then break $out else ... end)

次の記述は構文エラーになります。

break $out

$outというラベルを参照できないからです。

エラー抑制/オプショナル演算子: ?

?演算子はEXP?のように記述します。 この場合はtry EXPの省略形になります。

Example
jq '[.[]|(.a)?]'
Input[{}, true, {"a":1}]
Output [null, 1]

Perl互換の正規表現(PCRE)

jqはPHPやRubyやTextMateやSublime Textなどいろいろなソフトウェアが利用しているOniguruma正規表現ライブラリを利用しています。 このセクションではjqに関連する内容を説明します。

jqの正規表現フィルターは次のいずれかの記法で定義できます。

STRING | FILTER( REGEX )
STRING | FILTER( REGEX; FLAGS )
STRING | FILTER( [REGEX] )
STRING | FILTER( [REGEX, FLAGS] )

登場する要素の意味は次のとおりです。

  • STRING,REGEX,FLAGSはjqにおける文字列あるいは文字列の内挿に使用できるオブジェクトです
  • 文字列を内挿した後のREGEXはPCREに即した正規表現でなければなりません
  • FILTERは後述するtestmatchcaptureのいずれかです

FLAGSはOnigurumaが対応している次のいずれかの制御文字で構成された文字列です。

  • g - 全体検索(最初にマッチした文字列だけでなく、全ての文字列を検索します)
  • i - 大文字と小文字を区別しない検索
  • m - 複数行モード(.が改行文字にもマッチします)
  • n - 空のマッチを除外します
  • p - smを両方とも有効化します
  • s - 単一行モード(^\Aに、$\Zに相当します)
  • l - 最長マッチを探索します
  • x - 拡張正規表現を有効にします(空白やコメントを無視します)

例えば、xを指定した状態で空白文字をマッチするには次のように\sをエスケープします。

  • test( "a\\sb"; "x" )

正規表現REGEXの中で指定できる制御文字もあるので注意してください。 次のように記述すると、true, true, false, falseのように評価されます。

  • jq -n '("test", "TEst", "teST", "TEST") | test( "(?i)te(?-i)st" )'

test(val), test(regex; flags)

matchと同様ですが、正規表現がマッチした結果からマッチオブジェクトを生成せずtruefalseを生成します。

Examples
jq 'test("foo")'
Input"foo"
Output true
jq '.[] | test("a b c # spaces are ignored"; "ix")'
Input["xabcd", "ABC"]
Output true
true

match(val), match(regex; flags)

matchはマッチした内容を含むオブジェクトを生成します。 マッチオブジェクトは次のようなフィールドを持っています。

  • offset - UTF-8のコードポイントで数えた、入力の先頭からマッチした位置の先頭まで距離(オフセット)
  • length - UTF-8のコードポイントで数えた、マッチした文字列の長さ
  • string - マッチした文字列そのもの
  • captures - キャプチャグループそれぞれを要素とする配列

キャプチャグループのオブジェクトは次のようなフィールドを持っています。

  • offset - UTF-8のコードポイントで数えた、入力の先頭からマッチした位置の先頭まで距離(オフセット)
  • length - UTF-8のコードポイントで数えた、グループの文字列の長さ
  • string - キャプチャした文字列そのもの
  • name - キャプチャグループの名前(無ければnull

何もマッチしなかったキャプチャグループのoffset-1です。

Examples
jq 'match("(abc)+"; "g")'
Input"abc abc"
Output {"offset": 0, "length": 3, "string": "abc", "captures": [{"offset": 0, "length": 3, "string": "abc", "name": null}]}
{"offset": 4, "length": 3, "string": "abc", "captures": [{"offset": 4, "length": 3, "string": "abc", "name": null}]}
jq 'match("foo")'
Input"foo bar foo"
Output {"offset": 0, "length": 3, "string": "foo", "captures": []}
jq 'match(["foo", "ig"])'
Input"foo bar FOO"
Output {"offset": 0, "length": 3, "string": "foo", "captures": []}
{"offset": 8, "length": 3, "string": "FOO", "captures": []}
jq 'match("foo (?<bar123>bar)? foo"; "ig")'
Input"foo bar foo foo foo"
Output {"offset": 0, "length": 11, "string": "foo bar foo", "captures": [{"offset": 4, "length": 3, "string": "bar", "name": "bar123"}]}
{"offset": 12, "length": 8, "string": "foo foo", "captures": [{"offset": -1, "length": 0, "string": null, "name": "bar123"}]}
jq '[ match("."; "g")] | length'
Input"abc"
Output 3

capture(val), capture(regex; flags)

入力のJSONオブジェクトについて名前付きキャプチャグループを集めます。 グループの名前をキー、マッチした文字列を値とするオブジェクトを生成します。

Example
jq 'capture("(?<a>[a-z]+)-(?<n>[0-9]+)")'
Input"xyzzy-14"
Output { "a": "xyzzy", "n": "14" }

scan(regex), scan(regex; flags)

入力の文字列について、正規表現regexと制御文字列flagsにマッチした重複しない部分文字列を要素とするストリームを生成します。 マッチしなければストリームは空になります。 入力の文字列それぞれを全てキャプチャするには[ scan(regex) ]のようなイディオムで記述します。

split(regex; flags)

後方互換性を保つため、正規表現ではなく文字列で分割します。

splits(regex), splits(regex; flags)

対応するsplitと同じ結果になりますが、配列ではなくストリームを生成します。

sub(regex; tostring) sub(regex; string; flags)

入力の文字列について、正規表現regexにマッチした最初の部分文字列を内挿してからtostringした結果で置換します。 tostringはjq文字列でなければなりません。名前付きキャプチャグループの名前を含む場合もありmす。 実際のところ、tostringの入力はcaptureで生成した名前付きキャプチャグループのJSONオブジェクトです。 従って、参照するキャプチャグループの名前が"x"なら"\(.x)"のように記述しなければなりません。

gsub(regex; string), gsub(regex; string; flags)

subと同様ですが、マッチした重複しない部分文字列全てを内挿した結果で置換します。

高度な使い方(Advanced features)

変数はほとんどのプログラミング言語に必要不可欠な要素ですが、jqでは「高度な使い方」という扱いになります。

ほとんどのプログラミング言語において変数はデータの入れ物にすぎません。 計算した値を繰り返し使いたければ変数に記憶しなければならないのです。 値を他のプログラム部品へ渡すには、値を記録する場所である変数もプログラム部品の一部として定義しなければなりません(関数の引数やオブジェクトのメンバーなど)。

jqは関数を定義できるのですが、主な用途はjqの標準ライブラリを定義することです(mapfindなど多くの関数は実際にjqが定義しています)。

jqには還元処理のための演算子があります。 とても強力ですが少し分かりにくい機能です。 繰り返しになりますが、基本的には標準ライブラリとして提供するいくつかの便利な機能を定義するために内部で使用するものです。

初めて見るときは分かりにくいかもしれませんが本来jqはジェネレーターです(他のプログラミング言語によくある機能です)。 いくつかの便利機能はジェネレーターを作りやすくするためにあるのです。

最小限の入出力(標準入力からJSONを読み取ったり、標準出力へJSONを書き込んだり)に対応しています。

最後になりますが、jqはモジュールおよびライブラリで構成されたシステムです。

変数・記号の束縛演算子: ... as $identifier | ...

jqでは全てのフィルターが入力と出力を持っているので、隣のプログラム部品に値を渡すため手作業であれこれする必要はありません。 a + bのような大部分の式で、入力を部分式へ分配するようになっています(abは同じ入力を受け取るということです)。 ですから、たいていの場合値を繰り返し使うために変数が必要になることはないのです。

例えば、数値の配列について平均値を計算する場合、たいていのプログラミング言語ならいくつか変数が必要になるでしょう。 少なくとも配列を保持するための変数が1つ、場合によってはそれぞれの要素を保持したりループ回数を数えるためにもう1つ必要になるでしょう。 jqではadd / lengthと記述するだけです。 式addは入力した配列の総和を生成し、式lengthは入力した配列の長さを生成するからです。

従って、基本的にjqではほとんどの問題を変数を使うことなくきれいに解決できます。 それでも変数を使うほうが分かりやすくなる場合もあるので、expression as $variableという記法で変数を定義できるようになっています。 変数名は$から始めます。 次の例は配列の平均値を計算する不細工なバージョンです。

length as $array_length | add / $array_length

実際に変数を導入したほうが簡単になる、もっと複雑な問題が必要ですね。

ブログの投稿を要素とする配列があることにします。 それぞれの要素は"author"、"title"、"realnames"をフィールドに持っています。 "realnames"は投稿者のユーザー名と本名からなる連想配列です。 具体的には次のようになります。

{"posts": [{"title": "Frist psot", "author": "anon"},
           {"title": "A well-written article", "author": "person1"}],
 "realnames": {"anon": "Anonymous Coward",
               "person1": "Person McPherson"}}

ここで、それぞれのブログの投稿に投稿者の本名を持たせることを考えます。 具体的には次のようになります。

{"title": "Frist psot", "author": "Anonymous Coward"}
{"title": "A well-written article", "author": "Person McPherson"}

そこで本名を含むオブジェクトrealnamesを変数$namesへ格納します。 そうすれば残りの式でユーザー名から本名を参照できるようになります。

.realnames as $names | .posts[] | {title, author: $names[.author]}

exp as $x | ...と記述すると、全ての入力についてexpの値を格納した変数$xと共にパイプラインの後続部分を実行できます。 asはforeachによる繰り返しのように働くのです。

{foo: .foo}という記述の省略形が{foo}であるのと同様に、{$foo}という記述は{foo: $foo}という記述の省略形です。

asは入力のデータ構造に合わせることで複数の変数を宣言できます("オブジェクトの解体"と呼ばれています)。

. as {realnames: $names, posts: [$first, $second]} | ...

. as [$first, $second]のように配列で変数を宣言することもできます。 入力した配列の先頭からそれぞれの要素を変数に束縛していきます。 入力した配列へ配列パターンに対応する要素がなければ変数にはnullが設定されます。

変数の有効範囲は宣言した位置から後ろ全てです。 次のような記述は意図したように機能します。

.realnames as $names | (.posts[] | {title, author: $names[.author]})

しかし、次のような記述は意図したように機能しません。

(.realnames as $names | .posts[]) | {title, author: $names[.author]}

プログラミング言語理論の専門家には、jqの変数がレキシカルスコープに束縛されると説明するほうが正確でしょう。 一度値を束縛した変数に別の値を束縛する方法はありません。 新たに同じ名前の変数を生成するだけで、元の値に束縛した変数は参照できなくなります。

Examples
jq '.bar as $x | .foo | . + $x'
Input{"foo":10, "bar":200}
Output 210
jq '. as $i|[(.*2|. as $i| $i), $i]'
Input5
Output [10,5]
jq '. as [$a, $b, {c: $c}] | $a + $b + $c'
Input[2, 3, {"c": 4, "d": 5}]
Output 9
jq '.[] as [$a, $b] | {a: $a, b: $b}'
Input[[0], [0, 1], [2, 1, 0]]
Output {"a":0,"b":null}
{"a":0,"b":1}
{"a":2,"b":1}

解体(代替)演算子: ?//

解体(代替)演算子はさまざまな形式の入力を解体するための簡潔な仕組みを提供します。

リソースとリソースに結びつくイベントの一覧を返すAPIがあるとします。 そして、それぞれのリソースについてユーザーIDと最初に登場するイベントのタイムスタンプを取得したいことにします。 このAPIの応答は、リソースに複数のイベントが結びつく場合だけイベントを配列にするようです(XMLから変更したようであまりいい構造ではありません)。

{"resources": [{"id": 1, "kind": "widget", "events": {"action": "create", "user_id": 1, "ts": 13}},
               {"id": 2, "kind": "widget", "events": [{"action": "create", "user_id": 1, "ts": 14}, {"action": "destroy", "user_id": 1, "ts": 15}]}]}

解体(代替)演算子を使うとそういう構造のデータを簡潔に処理できます。

.resources[] as {$id, $kind, events: {$user_id, $ts}} ?// {$id, $kind, events: [{$user_id, $ts}]} | {$user_id, $kind, $id, $ts}

入力が値の配列なのかオブジェクトなのかわからない場合は次のように記述できます。

.[] as [$id, $kind, $user_id, $ts] ?// {$id, $kind, $user_id, $ts} | ...

演算子の両側で同じ変数を定義する必要はありません。 しかし、後続の式では全ての変数が有効になります。 演算子の入力にマッチしなかった側で定義した変数の値はnullになります。

.resources[] as {$id, $kind, events: {$user_id, $ts}} ?// {$id, $kind, events: [{$first_user_id, $first_ts}]} | {$user_id, $first_user_id, $kind, $id, $ts, $first_ts}

Additionally, if the subsequent expression returns an error, the alternative operator will attempt to try the next binding. Errors that occur during the final alternative are passed through. 加えて、後続の式がエラーを返す場合、演算子はもう一方の代替パターンで変数の束縛を試みます。 最後の代替パターンまで全てエラーを返す場合、その処理はエラーで終了します。

[[3]] | .[] as [$a] ?// [$b] | if $a != null then error("err: \($a)") else {$a,$b} end
Examples
jq '.[] as {$a, $b, c: {$d, $e}} ?// {$a, $b, c: [{$d, $e}]} | {$a, $b, $d, $e}'
Input[{"a": 1, "b": 2, "c": {"d": 3, "e": 4}}, {"a": 1, "b": 2, "c": [{"d": 3, "e": 4}]}]
Output {"a":1,"b":2,"d":3,"e":4}
{"a":1,"b":2,"d":3,"e":4}
jq '.[] as {$a, $b, c: {$d}} ?// {$a, $b, c: [{$e}]} | {$a, $b, $d, $e}'
Input[{"a": 1, "b": 2, "c": {"d": 3, "e": 4}}, {"a": 1, "b": 2, "c": [{"d": 3, "e": 4}]}]
Output {"a":1,"b":2,"d":3,"e":null}
{"a":1,"b":2,"d":null,"e":4}
jq '.[] as [$a] ?// [$b] | if $a != null then error("err: \($a)") else {$a,$b} end'
Input[[3]]
Output {"a":null,"b":3}

関数の定義

"def"記法によりフィルターに名前を付けられます。

def increment: . + 1;

そうするとincrementは他の組み込みフィルターと同じように使えるようになります(実際にたくさんの組み込みフィルターはそうやって定義されています)。 関数は引数を取ることができます。

def map(f): [.[] | f];

引数は_フィルター_として(引数無しの関数として)渡されます。値では_ありません_。 同じ引数が異なる入力に対して複数回参照される場合があります(次の例では入力した配列のそれぞれの要素にfを適用します)。 関数の引数は値というよりコールバック関数のように機能します。 これは重要なので理解しておかなければなりません。 次の例で考えてみましょう。

def foo(f): f|f;
5|foo(.*2)

f.*2なので、結果は20になるはずです。 最初にfを評価したときは.が5で、2回目にfを評価した結果は10(5*2)になるので、全体の結果は20になるのです。 関数の引数もフィルターです。 フィルターは入力を受け取った時点で評価されるのです。

単純な関数として引数には値のように振る舞って欲しい場合、次のように変数を使うことができます。

def addvalue(f): f as $f | map(. + $f);

あるいは単純に次のように記述できます。

def addvalue($f): ...;

どちらの記法でもaddvalue(.foo)と記述した場合、入力したオブジェクトのフィールド.fooを配列のそれぞれの要素に加算します。 addvalue(.[])のように記述してはいけません。 そうするとmap(. + $f)の部分が.のそれぞれの値ごとに評価されてしまうからです。

同じ名前の関数を複数定義することができます。 引数の数が同じなら後で定義した関数が前の定義を置換します。 つまり後続の指揮で参照できるのは最後に定義した関数になるのです。 詳しくは後述するスコープの説明を参照してください。

Examples
jq 'def addvalue(f): . + [f]; map(addvalue(.[0]))'
Input[[1,2],[10,20]]
Output [[1,2,1], [10,20,10]]
jq 'def addvalue(f): f as $x | map(. + $x); addvalue(.[0])'
Input[[1,2],[10,20]]
Output [[1,2,1,2], [10,20,1,2]]

スコープ

jqには2種類の記号があります。 値を束縛する記号と関数です。 どちらもレキシカルスコープで定義します。 「自分より左側」で定義した変数や関数しか参照できません。 この規則の例外は、関数の定義から自分自身を名前で参照できることです。 つまり再帰関数を定義できるのです。

例えば、式... | .*3 as $times_three | [. + $times_three] | ...では「変数定義より右側」の式からは変数を参照できますが、「変数定義より左側」の式からは変数を参照できません。 式`... | (.*3 as $times_three | [. + $times_three]) | ...``では閉じ括弧より右側の式から変数を参照_できません_。

還元

reduce記法を使うと全ての要素に何らかの式を適用した結果を累積し、単一の結果を生成できます。 例えば次の式に[3,2,1]を入力してみましょう。

reduce .[] as $item (0; . + $item)

.[]の生成するそれぞれの結果について0から初めて. + $itemを実行し、合計を算出します。 この例では.[]は3、2、1を生成するので、次のような計算をするのと同じ意味になります。

0 | (3 as $item | . + $item) |
    (2 as $item | . + $item) |
    (1 as $item | . + $item)
Example
jq 'reduce .[] as $item (0; . + $item)'
Input[10,2,5,3]
Output 20

isempty(exp)

expが何も出力しなければ真を返します。それ以外では偽を返します。

Example
jq 'isempty(empty)'
Inputnull
Output true

limit(n; exp)

組み込み関数limitは式expの出力から最大n個の要素を取り出します。

Example
jq '[limit(3;.[])]'
Input[0,1,2,3,4,5,6,7,8,9]
Output [0,1,2]

first(expr), last(expr), nth(n; expr)

組み込み関数first(expr)は式exprの出力から先頭の要素を取り出します。 組み込み関数last(expr)は式exprの出力から最後の要素を取り出します。

組み込み関数nth(n; expr)は式exprの出力からn番目の要素を取り出します。 次のように定義しても同じように機能します。 def nth(n; expr): last(limit(n + 1; expr)); なお、組み込み関数nthは負の値に対応していません。

Example
jq '[first(range(.)), last(range(.)), nth(./2; range(.))]'
Input10
Output [0,9,5]

first, last, nth(n)

組み込み関数firstは入力した配列から先頭の要素を取り出します。 組み込み関数lastは入力した配列から最後の要素を取り出します。

組み込み関数nth(n)は入力した配列からn番目の要素を取り出します。

Example
jq '[range(.)]|[first, last, nth(5)]'
Input10
Output [0,9,5]

foreach

foreach記法はreduceと似ていますが、limitの作成や還元処理の途中で中間結果を生成するために用意されています(具体例を参照してください)。

次のように記述します。 foreach EXP as $var (INIT; UPDATE; EXTRACT) reduceと同様に、INITは最初に1度だけ評価され状態値を生成します。 そして式EXPの出力するそれぞれの要素を変数$varへ束縛し、$varと現在の状態値の元で式UPDATEを評価します。 式UPDATEの結果により状態値を更新します。 最後に、生成されたそれぞれの状態値について式EXTRACTを評価し、foreachの出力を生成します。

基本的にはreducelimitのような関数を作成する場合に便利な機能です。 しかし、それよりも部分的な還元処理をする場合のほうが一般的でしょう(具体例を参照してください)。

Example
jq '[foreach .[] as $item ([[],[]]; if $item == null then [[],.[0]] else [(.[0] + [$item]),[]] end; if $item == null then .[1] else empty end)]'
Input[1,2,3,4,null,"a","b",null]
Output [[1,2,3,4],["a","b"]]

再帰

前述のとおりrecurseは再帰を利用します。 そして全てのjq関数は再帰呼び出し可能です。 組み込みのwhile記法も再帰で実装されています。

再帰呼び出しの左側の式の値が最後に出力する値なら、その再帰呼び出しは末尾最適化できます。 実際のところ、再帰呼び出しの左側の式は入力のそれぞれの値に対して1つ以上の値を出力するべきではありません。

具体的には次のようにします。

def recurse(f): def r: ., (f | select(. != null) | r); r;

def while(cond; update):
  def _while:
    if cond then ., (update | _while) else empty end;
  _while;

def repeat(exp):
  def _repeat:
    exp, _repeat;
  _repeat;

ジェネレータとイテレータ

jqの提供する演算子や関数には、入力のそれぞれの値に対して0個、1個、あるいはそれ以上の値を出力するまさにジェネレータと呼ぶものがあります。 他のプログラミング言語ではちょうど1個だけ出力するものをジェネレータと呼んでいます。 例えば.[]は入力された全ての値を生成します(入力は配列やオブジェクトでなければなりません)。 またrange(0; 10)は0から10までの数値列を生成します。

カンマ演算子もジェネレータです。 カンマの左側の式が値を生成してから、右側の式が値を生成するからです。

組み込み関数emptyは0個の出力を生成するジェネレータです。 先行する式(ジェネレータ)の生成する値を無効化するのです。

全てのjq関数は組み込みのジェネレータと同じようにジェネレータとして利用できます。 再帰記法とカンマ演算子だけで新しいジェネレータを定義することもできます。 再帰呼び出しが「末尾」にあるならより効率的に動作するジェネレータになります。 次の具体例の関数_rangeは末尾で自分自身を再帰呼び出ししています。 この例は末尾再帰、ジェネレータコンストラクタ、部分関数という3種類の高度な要素を示しています。

Examples
jq 'def range(init; upto; by): def _range: if (by > 0 and . < upto) or (by < 0 and . > upto) then ., ((.+by)|_range) else . end; if by == 0 then init else init|_range end | select((by > 0 and . < upto) or (by < 0 and . > upto)); range(0; 10; 3)'
Inputnull
Output 0
3
6
9
jq 'def while(cond; update): def _while: if cond then ., (update | _while) else empty end; _while; [while(.<100; .*2)]'
Input1
Output [1,2,4,8,16,32,64]

数学機能(Math)

現在のjqはIEEE754で規定された64ビットの倍精度浮動小数点にのみ対応しています。

jqは+のように単純な算術演算子だけでなく、C言語の数学ライブラリが提供する標準的な数学関数を提供しています。 C言語の数学関数の中でsin()のように1引数の関数を、jqでは引数無しの関数として提供しています。 pow()のように2引数の関数は、入力.を無視する2引数の関数として提供しています。 3引数の関数は、入力.を無視する3引数の関数として提供しています。

標準的な数学関数の中でどれが利用できるかは、OSとC言語の数学ライブラリの提供する数学関数に依存しています。 利用できない関数を呼び出した場合、エラーをレイズするでしょう。

C言語の数学関数(1引数): acos acosh asin asinh atan atanh cbrt ceil cos cosh erf erfc exp exp10 exp2 expm1 fabs floor gamma j0 j1 lgamma log log10 log1p log2 logb nearbyint pow10 rint round significand sin sinh sqrt tan tanh tgamma trunc y0 y1.

C言語の数学関数(2引数): atan2 copysign drem fdim fmax fmin fmod frexp hypot jn ldexp modf nextafter nexttoward pow remainder scalb scalbln yn.

C言語の数学関数(3引数): fma.

それぞれの関数に関するより詳しい情報はシステムのマニュアルを参照してください。

入出力(I/O)

今のところjqの提供する入出力機能は大半が入力の読み取りを制御するための最小限ものだけです。 組み込み関数inputinputsが対応します。 標準入力やコマンドラインに指定したファイルなど、jqの読み取り機能と同じ入力源から読み取ります。 jqの読み取り機能とこれらの関数は交互に動作します。

最小限の出力機能を提供するのが組み込み関数debugstderrです。 (jqプログラムは常に標準出力へJSON文字列を出力することを思い出しましょう)。 debugはjqを直接実行するのではなく、libjqのC言語APIを利用するアプリケーションに固有の振る舞いをもたらします。 stderrは入力を改行文字も含めて一切加工せずに文字列として標準エラー出力へ出力します。

jqのほとんどの組み込み機能には参照等価性があります。 同じ入力を与えるとまったく同じ値のストリームを繰り返し生成できるのです。 ただし、入出力機能についてはそうなりません。

input

入力から受け取った1つの値を出力します。

inputs

入力から受け取った全ての値を1つずつ出力します。

主にjqへの入力を集計するのに便利です。

debug

入力した値に応じたデバッグメッセージを生成します。 jqコマンドでは入力した値を["DEBUG":, <input-value>]という形式にして改行と共に標準エラー出力へ出力します。 将来変更するかもしれません。

stderr

改行を含めて入力を変更せず標準エラー出力へ出力します。

input_filename

フィルター処理している入力を読み取ったファイル名を返します。 jqを実行しているときのロケールがUTF-8でない場合は機能しません。

input_line_number

フィルター処理している入力の行番号を返します。

ストリーム(Streaming)

jqを--streamオプションと共に実行すると、入力の文字列をストリームとして解釈します。 巨大なJSON文字列を全て解析することなくフィルター処理を始められるようになります。 もし1GBのJSON文字列があるとしたら、ストリームにすればより早く処理できるようになります。

しかし、入力が[<path>, <leaf-value>]のような形式の場合(他にもいくつかそういう形式があります)、 それほど簡単にストリームとして扱えるわけではありません。

ストリームの処理を簡単にするためのさまざまな組み込み機能を提供しています。

例えば[0,[1]]を入力したときのストリーム形式は[[0],0],[[1,0],1],[[1,0]],[[1]]のようになります。

ストリーム形式に含まれるのは[<path>, <leaf-value>](任意のスカラー値や空の配列、空のオブジェクトを表します)と [<path>](配列やオブジェクトの終端)です。 jqの将来のバージョンでは--stream-seqを指定すると、入力した文字列の解釈に失敗したことを示す["error message"]のような形式も出力できるようになる予定です。

truncate_stream(stream_expression)

straem_expressionの生成するストリームについて、左側から数えて入力した数値に対応する位置より後ろを切り捨てた結果を生成します。

Example
jq '[1|truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]])]'
Input1
Output [[[0],2],[[0]]]

fromstream(stream_expression)

stream_expressionの生成するストリームに対応する値を生成します。

Example
jq 'fromstream(1|truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]]))'
Inputnull
Output [2]

tostream

組み込み関数tostreamは入力した値を対応するストリーム形式へ変換した結果を生成します。

Example
jq '. as $dot|fromstream($dot|tostream)|.==$dot'
Input[0,[1,{"a":1},{"b":2}]]
Output true

代入(Assignment)

jqの代入は他のプログラミング言語と比べて少し異なる機能になっています。 jqでは参照とコピーを区別しません。 つまり、2つのオブジェクトあるいは配列があるとして、それらは等しいか等しくないかというだけで、「同じオブジェクトである」とか「同じオブジェクトではない」とかそういうことを判断しないのです。

あるオブジェクトに2つのフィールド.foo.barがあるとしましょう。いずれも値は配列です。 そして、.bar = .fooのように代入してから.fooに何らかの値を追加しても、.barの値は変化しません。 PythonやJava、RubyやJavaScriptなどのプログラミング言語を使ったことがあるなら、 jqは代入するときにオブジェクト全体をディープコピーしているものと考えることができます。 (性能の都合もあるので完全にそういう処理をしているわけではありませんが基本的な考え方としては合っています)

つまりjqでは値を循環させられないということです(例えば配列の先頭要素が配列自身を参照するような構造)。 これは完全に意図的な設計で、jqがどのような出力を生成しても必ずJSONで表現できることを保証します。

jqにおける代入演算子は左辺(LHS、left-hand side)にパス式を指定します。 右辺(RHS、right-hand side)には、左辺のパス式から導かれたパスに設定する値を指定します。

jqでは値は常に変更不能(イミュータブル)です。 内部的には、代入する値に必要な情報を全て保持する入力.から新しい値を還元的に計算し、出力しています。 具体的には次のような例を読めばはっきりします。 {a:{b:{c:1}}} | (.a.b|=3), . この式は{"a":{"b":3}}{"a":{"b":{"c":1}}}を出力します。 最後の式は.なので入力した値を変更せずそのまま出力するからです。

ほとんどの利用者は=ではなく|=+=のような変化形を使うでしょう。

代入演算子のLHSも入力.を参照するので注意してください。 つまり、$var.foo = 1と記述しても意図したように動作しません($var.fooという記述は入力.のパス式としては便利ですが不正な記法です)。 $var | .foo = 1のように記述しましょう。

.a,.b=0という記述は.aにも.bにも値を代入しません。 (.a,.b)=0のように記述すれば両方に値を代入します。

自己代入演算子: |=

右辺のフィルター式が入力.から生成した新しい値を代入します。 例えば(.foo, .bar) |= .+1と記述すると、フィールドfooには入力したオブジェクトのフィールドfooに1を加算した値、フィールドbarには入力したオブジェクトのフィールドbarに1を加算した値を代入します。

左辺には任意のパス式を指定できます。詳しくはpath()の説明を参照してください。

左辺で入力.の値を参照している場合は注意が必要です。 つまり$var.foo |= . + 1と記述しても意図したように動作しません($var.fooという記述は入力.のパス式としては便利ですが不正な記法です)。 $var | .foo |= . + 1のように記述しましょう。

右辺が何も値を出力しなければ(emptyなど)左辺のパスに対応する要素は削除します(del(path)と同様です)。

右辺が複数の値を出力する場合、最初の値だけを使用します。 (互換性の注意点:jq1.5以前のバージョンでは最後の値だけを使うようになっていました)

Example
jq '(..|select(type=="boolean")) |= if . then 1 else 0 end'
Input[true,false,[5,true,[true,[false]],false]]
Output [1,0,[5,1,[1,[0]],0]]

算術自己代入演算子: +=, -=, *=, /=, %=, //=

jqにはa op= bという形式の代入演算子を複数提供しています。 いずれもa |= . op bと記述したのと同じ意味になります。 つまり値をインクリメントする+= 1|= . + 1と記述するのと同じ結果になります。

Example
jq '.foo += 1'
Input{"foo": 42}
Output {"foo": 43}

代入演算子: =

基本的な代入演算子です。 他の代入演算子と違って右辺と左辺に同じ入力が渡されます。 左辺にどんなパス式を指定しても、右辺の生成する全ての出力が使われます(詳しくは後述します)。

右辺が複数の値を生成する場合、それぞれの値を左辺値のパスに対応する名前に設定し、変更された.を出力します。 例えば(.a,.b)=range(2)と記述すると{"a":0,"b":0}{"a":1,"b":1}を出力します。 前に説明した自己代入演算子ならそうはなりません。

次の例は間違いなく=|=の違いを説明してくれます。

'{"a": {"b": 10}, "b": 20}'を次のような式に入力してみましょう。

.a = .b

.a |= .b

前の式は入力したオブジェクトのフィールド"a"にフィールド"b"の値を代入し、{"a": 20, "b": 20}を出力します。 後の式は入力したオブジェクトのフィールド"a"にフィールド"a"の値であるオブジェクトのフィールドb"の値を代入し、{"a": 10, "b": 20}を出力します。

他にも=|=の違いを示す例があります。

null|(.a,.b)=range(3)

この式は'{"a":0,"b":0}, {"a":1,"b":1}, {"a":2,"b":2}'を出力します。 ですが次の式は'{"a":0,"b":0}'を出力します。

null|(.a,.b)|=range(3)

複雑な代入

他のプログラミング言語と違ってjqの代入演算子の左辺ではいろいろなことが許可されています。 これまで説明してきたのは単純なフィールドアクセスでしたが、配列アクセスができるとしても驚くことではありません。

.posts[0].title = "JQ Manual"

左辺の式が入力ドキュメントを別の視点から参照する複数の結果を生成するとしたら驚かされることになります。

.posts[].comments |= . + ["this is great"]

この例は入力に含まれるそれぞれのブログ投稿が持つフィールド"comments"の配列値へ文字列"this is great"を追加します(入力はオブジェクトでフィールド"posts"の値はブログ投稿の配列です)。

jqはa = bのような代入を発見すると、aに渡された入力ドキュメントの部分を選択するため"path"を記録します。 記録したパスで入力オブジェクトから代入する部分を探索します。 左辺では任意のフィルターを使用できるので、結果として代入するときは入力から任意のパスを選択できることになるのです。

これはとても強力な操作です。 ブログの投稿にコメントを追加したければ、同じように"blog"を入力に与えればいいからです。 仮に"stedolan"の投稿にだけコメントを追加したければ、組み込み関数selectで対象のブログ投稿を探索できるからです。

.posts[] | select(.author == "stedolan")

この操作により得られるパスは"stedolan"のブログ投稿だけを指定することになるので、前の例と同じようにコメントを追加できます。

(.posts[] | select(.author == "stedolan") | .comments) |=
    . + ["terrible."]

モジュール(Modules)

jqにはライブラリ(モジュール)システムがあります。 モジュールファイルの拡張子は.jqです。

プログラムの取り込むモジュールは初期探索パス(後述します)から探索します。 import命令とinclude命令は探索パスを変更できます。

探索パスから発見したパスはさまざまな置換の対象になります。

パスが"~/"から開始するときは、"~"をユーザーのホームディレクトリへ置換します。

パスが"$ORIGIN/"から開始するときは、"$ORIGIN"はjqコマンドの配置されたパスへ置換します。

パスが"./"から開始するときは、"."はそのモジュールを取り込んでいるファイルの配置されたパスへ置換します。 プログラムをコマンドラインで指定したときは、jqコマンドを実行したディレクトリへ置換します。

import命令には初期探索パスに追加する探索パスを指定できます。

初期探索パスはコマンドラインオプションの-Lで指定できます。 指定しなかったときは["~/.jq", "$ORIGIN/../lib/jq", "$ORIGIN/../lib"]になります。

探索パスについてモジュールを探索しているとき、nullや空文字列に到達したら探索は中止します。

"foo/bar"のように相対パスで記述された依存モジュールは、探索パスから"foo/bar.jq"および"foo/bar/bar.jq"を探索します。 これは、バージョン管理システムのファイルやREADMEファイルと共にディレクトリとしてモジュールを配置したり、単独のファイルとして配置するための機能です。

曖昧さを回避するため、"foo/foo"のように同じ名前が繰り返し登場するコンポーネント名は利用できません。

つまり探索パスを-L$HOME/.jqとしたとき、モジュールfoo$HOME/.jq/foo.jq$HOME/.jq/foo/foo.jqのいずれかになります。

"$HOME/.jq"がファイルならメインプログラムへ取り込みます。

import RelativePathString as NAME [<metadata>];

相対パスで指定したモジュールを探索パスから探索し、発見したモジュールを取り込みます。 探索中に相対パスへ拡張子".jq"を追加する場合もあります。 モジュールのシンボルには接頭辞"NAME::"がつきます。

任意指定可能なメタデータは定数のjq式でなければなりません。 "homepage"などのキーからなるオブジェクトにするべきです。 現在のjqはメタデータの含むキー"search"の値だけを利用します。 モジュールの利用者は組み込み関数modulemetaでメタデータへアクセスできます。

メタデータにキー"search"があるとして、その値は文字列あるいは文字列の配列でなければなりません。 指定された探索パスは、探索時にトップレベル探索パスからの相対パスとして解決します。

include RelativePathString [<metadata>];

相対パスで指定したモジュールを探索パスから探索し、発見したモジュールを今のコンテキストへ取り込みます。 探索中に相対パスへ拡張子".jq"を追加する場合もあります。 モジュールのシンボルは呼び出し側の名前空間に取り込まれます。

任意指定可能なメタデータは定数のjq式でなければなりません。 "homepage"などのキーからなるオブジェクトにするべきです。 現在のjqはメタデータの含むキー"search"の値だけを利用します。 モジュールの利用者は組み込み関数modulemetaでメタデータへアクセスできます。

import RelativePathString as $NAME [<metadata>];

相対パスで指定したJSONファイルを探索パスから探索し、発見したJSONファイルを取り込みます。 探索中に相対パスへ拡張子".json"を追加する場合もあります。 ファイルの内容は$NAME::NAMEのように参照できるようになります。

任意指定可能なメタデータは定数のjq式でなければなりません。 "homepage"などのキーからなるオブジェクトにするべきです。 現在のjqはメタデータの含むキー"search"の値だけを利用します。 モジュールの利用者は組み込み関数modulemetaでメタデータへアクセスできます。

メタデータにキー"search"があるとして、その値は文字列あるいは文字列の配列でなければなりません。 指定された探索パスは、探索時にトップレベル探索パスからの相対パスとして解決します。

module <metadata>;

完全に任意な命令です。 正常な操作に必要な命令ではありません。 組み込み関数modulemetaが読み取るメタデータを提供するのが目的です。

メタデータは定数のjq式でなければなりません。 "homepage"などのキーからなるオブジェクトにするべきです。 現在のjqはメタデータの含むキー"search"の値だけを利用します。 モジュールの利用者は組み込み関数modulemetaでメタデータへアクセスできます。

modulemeta

入力したモジュール名に対するモジュールのメタデータをオブジェクトとして出力します。 キー"deps"には、指定したモジュールが取り込んでいるモジュールをメタデータと共に配列で出力します。

プログラムはこの組み込み関数でモジュールのメタデータを取得できます。 取得したメタデータから存在しない依存モジュールを検索したり、ダウンロードしたり、インストールすることができるでしょう。

色付け(Colors)

別の設定で色付けするには、環境変数JQ_COLORSにコロン(U+003a)を区切り文字として端末制御文字を記述します。 指定する順序は次のとおりです。

  • null
  • false
  • true
  • 数値
  • 文字列
  • 配列
  • オブジェクト

デフォルトのカラースキーマと同じ設定は"JQ_COLORS=1;30:0;37:0;37:0;37:0;32:1;37:1;37"です。

ここではVT100/ANSIエスケープについて解説しません。 とはいえそれぞれの色定義はセミコロン(U+003b)で区切られた2つの数値で構成されています。 最初の数値は次のいずれかになります。

  • 1 (濃くする)
  • 2 (薄くする)
  • 4 (下線を引く)
  • 5 (点滅させる)
  • 7 (反転する)
  • 8 (非表示にする)

2番目の数値は次のいずれかになります。

  • 30 (黒)
  • 31 (赤)
  • 32 (緑)
  • 33 (黄)
  • 34 (青)
  • 35 (マゼンタ)
  • 36 (シアン)
  • 37 (シロ)