ようへいの日々精進XP

よかろうもん

jq メモ 〜 組み込み演算子を試す 〜

tl;dr

昨日の日記にもちょっと書いたけど、昨日は jq コマンドを利用して、配列に要素を追加する方法について試行錯誤していました。一夜明けて、改めてドキュメントを読んだり、jq play で試してみたのでメモしてきます。

stedolan.github.io

jqplay.org

jq play は初めて使ってみたけど、jq のフィルタをブラウザでシュッと試せるのが良いですな。

尚、本記事では、jq play で試した結果を貼り付けていますが、場合によっては、手元環境で実行した jq の実行結果を貼り付ける場合があります。手元の jq のバージョンは以下の通りです。

$ jq --version
jq-1.6

組み込み演算子について

型変換は行わない

ドキュメントより引用。

Some jq operator (for instance, +) do different things depending on the type of their arguments (arrays, numbers, etc.). However, jq never does implicit type conversions. If you try to add a string to an object you'll get an error message and no result.

組み込み演算子は、引数の型 (配列、数値など) によって、結果が変わる = 暗黙的に型変換は行わず、エラーになるとのこと。

+ (プラス) 演算子

数値

Numbers (数値) は、通常の算術で加算されます。

$ echo '{ "number": 100 }' | jq '.number + 100'
200

配列

Array (配列) は、より大きな配列に連結されて追加されます。

$ echo '{ "array": [] }' | jq '.array + [ 100, 200 ]'
[
  100,
  200
]

$ echo '{ "array": [] }' | jq '.array + [ {"foo": 1}, {"bar": 2} ]'
[
  {
    "foo": 1
  },
  {
    "bar": 2
  }
]

ちなみに、異なる型 (数値) を追加しようとすると、以下のようにエラーが出ます。

$ echo '{ "array": [] }' | jq '.array + 100'
jq: error (at <stdin>:1): array ([]) and number (100) cannot be added

文字列

String (文字列) は、文字列が結合されます。

$ echo '{ "string": "foo" }' | jq '.string + "bar"'
"foobar"

オブジェクト

Object (オブジェクト) は、マージされる (右辺と左辺に同じキーがある場合、右辺のオブジェクトで上書きされる) 、再帰的なマージは * 演算子を使います。

$ echo '{ "object1": {} }' | jq '.object1 + { "object2": {} }'
{
  "object2": {}
}

$ echo '{ "object1": {} }' | jq '. + { "object2": {} }'
{
  "object1": {},
  "object2": {}
}

# = を付与すると、object1 キーの値として追加される
$ echo '{ "object1": {} }' | jq '.object1 += { "object2": {} }'
{
  "object1": {
    "object2": {}
  }
}

null

null は、値そのものを返すようです。

$ echo '{ "null": 1 }' | jq '.null + null'
1
$ echo '{ "null": "null" }' | jq '.null + null'
"null"
$ echo '{ "null": [] }' | jq '.null + null'
[]
$ echo '{ "null": {} }' | jq '.null + null'
{}

- (マイナス) 演算子

マイナス演算子は、算術演算子の減算と同じような挙動となるようです。

例えば、値が数値の場合には、以下のような結果となります。

$ echo '{ "number": 100 }' | jq '.number - 99'
1

配列の場合には、以下のように要素が削除されるような結果となります。

$ echo '{ "array": [1, 99] }' | jq '.array - [99]'
[
  1
]

* とか / とか % とか

* とか /% 演算子も用意されているようなので、ドキュメントに掲載されている内容を元に、簡単に試してみました。

まずは、* を試してみる。

$ echo 5 | jq '. * 10'
50

$ echo '{"foo": 1}' | jq '. * {"bar": 1}'
{
  "foo": 1,
  "bar": 1
}

$ echo null | jq '{"k": {"a": 1, "b": 2}} * {"k": {"a": 0,"c": 3}}'
{
  "k": {
    "a": 0,
    "b": 2,
    "c": 3
  }
}

次は、/ を試してみる。

$ echo 10 | jq '. / 10'
1

殆ど使うことがないであろう。

以上

jq の組み込み演算子を試してみました。jq 奥深いですな。