■ はじめに
AWS CLI からのレスポンスがJSONなので そこから値を取得する必要がある。 そこで調べてみたら jqコマンド ってのがみつかったのでメモ。
目次
【1】参考にできるサイト 1)ドキュメント 2)動画 【2】環境設定 1)Linux の場合 2)Windows の場合 【3】コマンドオプション 1)-r オプション 2)-f オプション 【4】使用上の注意 1)jq -f <file>で行う場合、改行コードはLFにしておくこと 【5】基本的な文法 1)「.」 2)SELECT 3)map 4)if-then-else 5)変数定義(as) 6)代替演算子(//) 【6】サンプル 例1:Windows環境下での実行 例2:Linux環境下での実行 例3:JSON の扱い 例4:複雑なJSON
【1】参考にできるサイト
1)ドキュメント
https://jqlang.github.io/jq/manual/
2)動画
https://dotinstall.com/lessons/basic_jq
【2】環境設定
1)Linux の場合
yumコマンド
sudo yum -y install epel-release sudo yum -y install jq
2)Windows の場合
[1] 以下のサイトから、「jq-win64.exe」をダウンロードし、 任意の場所に置く
https://stedolan.github.io/jq/
[2] コマンドプロンプトを立ち上げて、[1]の場所まで移動 [3] 「jq-win64.exe --version」を入力 => 今回は「jq-1.6」が出力される
補足:任意設定
* 以下のようにしておくと、Linuxライクに使える [1] 「jq-win64.exe」を「jq.exe」にリネーム [2] 環境変数 Path にjq.exeまでのパスを追加(例:Path=C:\soft\) [3] コマンドプロンプトを立ち上げて、「jq --version」を入力 => 今回は「jq-1.6」が出力される
【3】コマンドオプション
1)-r オプション
囲み文字であるダブルクォートが除去
2)-f オプション
* フィルタ情報をファイルで指定 (-f | --from-file <file>) => JSONファイルから別形式のJSONが出力した時などに使える
https://www.tohoho-web.com/ex/jq.html#opt-from-file
* 以下のサイトで行われていることを「-f」オプションを使ってみる
https://www.digitalocean.com/community/tutorials/how-to-transform-json-data-with-jq
# [1] まずは、データの確認 less seaCreatures.json ~~~~ [ { "name": "Sammy", "type": "shark", "clams": 5 }, { "name": "Bubbles", "type": "orca", "clams": 3 }, { "name": "Splish", "type": "dolphin", "clams": 2 }, { "name": "Splash", "type": "dolphin", "clams": 2 } ] ~~~~ # [2] 同じことをやってみる(JSONファイルから別形式のJSONが出力された) jq '{ creatures: map(.name), totalClams: map(.clams) | add, totalDolphinClams: map(select(.type == "dolphin").clams) | add }' seaCreatures.json ~[出力結果]~~~ { "creatures": [ "Sammy", "Bubbles", "Splish", "Splash" ], "totalClams": 12, "totalDolphinClams": 4 } ~~~~ # [3] 「{ creatures: ... add }'」部分をファイル化する vi template.jq ~~~~ { creatures: map(.name), totalClams: map(.clams) | add, totalDolphinClams: map(select(.type == "dolphin").clams) | add } ~~~~ # [4] [2] と同じ結果になることを確認する jq -f template.jq seaCreatures.json ~[出力結果]~~~ { "creatures": [ "Sammy", "Bubbles", "Splish", "Splash" ], "totalClams": 12, "totalDolphinClams": 4 } ~~~~~~
【4】使用上の注意
1)jq -f で行う場合、改行コードはLFにしておくこと
https://dk521123.hatenablog.com/entry/2024/04/19/121312
でやらかしたのだが、jq -f <file>を使う場合、ファイル(<file>)の改行コードは、 CRLFではなくLFにしておくこと => Windows環境下だけなら、気にしなくていいが、LFで統一した方が無難 => 以下「エラーメッセージ」のようになってしまう可能性がある
エラーメッセージ
jq: error: syntax error, unexpected INVALID_CHARACTER (Unix shell quoting issues?) at <top-level>, line1: {
【5】基本的な文法
1)「.」
* 「現在の入力」を表す
2)SELECT
* 値の抽出
例
$ echo '[{"name": "_Hello", "value": 25},{"name": "World", "value": 30}]' | jq '.[] | select(.name | startswith("_"))' { "name": "_Hello", "value": 25 } # 逆 $ echo '[{"name": "_Hello", "value": 25},{"name": "World", "value": 30}]' | jq '.[] | select(.name | startswith("_") | not)' { "name": "World", "value": 30 }
3)map
* 配列やオブジェクトを受け取り、配列を返却
例
$ echo '[1,2,3]' | jq -c 'map(. * 2)' [2,4,6]
4)if-then-else
* If 文で制御できる
https://jqlang.github.io/jq/manual/#if-then-else-end
5)変数定義(as)
* 変数を定義する
例
. as $file $file.violations[] as $violation
6)代替演算子(//)
* 値がない時の代替えするための演算子
例
# x が false や null でなければ x、さもなくば y x // y . // {}
【6】サンプル
例1:Windows環境下での実行
aws ssm get-parameters のレスポンスをパースする
https://docs.aws.amazon.com/cli/latest/reference/ssm/get-parameters.html
のレスポンスを使う
コマンド例
$ type sample.json | jq-win64.exe .Parameters[].Value "good day sunshine"
sample.json
{ "Parameters": [ { "Name": "helloWorld", "Type": "String", "Value": "good day sunshine", "Version": 1, "LastModifiedDate": 1542308384.49, "ARN": "arn:aws:ssm:us-east-1:123456789012:parameter/helloWorld" } ], "InvalidParameters": [] }
例2:Linux環境下での実行
https://dk521123.hatenablog.com/entry/2020/04/16/113816
にあるような開発環境下によって取得する値を変える
コマンド例
$ cat s3-setting.json | jq '.dev[]' "s3-bucket-dv001" "s3-bucket-dv002" "s3-bucket-dv003" $ cat s3-setting.json | jq -r '.prod.s3_bucket2' s3-bucket-pd002
s3-setting.json
{ "prod": { "s3_bucket1":"s3-bucket-pd001", "s3_bucket2":"s3-bucket-pd002", "s3_bucket3":"s3-bucket-pd003" }, "stage": { "s3_bucket1":"s3-bucket-sg001", "s3_bucket2":"s3-bucket-sg002", "s3_bucket3":"s3-bucket-pd003" }, "dev": { "s3_bucket1":"s3-bucket-dv001", "s3_bucket2":"s3-bucket-dv002", "s3_bucket3":"s3-bucket-dv003" } }
例3:JSON の扱い
* 最終的には、以下「input.json」の 「CRITICAL」又は「HIGH」の合算値を集計。 「CRITICAL」、「HIGH」がなかったら、「0」を返す
input.json
{ "CRITICAL": 1, "HIGH": 2, "MEDIUM": 3, "LOW": 4, "UNTRIGED": 5 }
コマンド例
$ cat input.json | jq 'keys' [ "CRITICAL", "HIGH", "LOW", "MEDIUM", "UNTRIGED" ] $ cat input.json | jq '. | to_entries' [ { "key": "CRITICAL", "value": 1 }, { "key": "HIGH", "value": 2 }, { "key": "MEDIUM", "value": 3 }, { "key": "LOW", "value": 4 }, { "key": "UNTRIGED", "value": 5 } ] $ cat input.json | jq '. | to_entries[] | select(.key=="CRITICAL" or .key=="HIGH")' { "key": "CRITICAL", "value": 1 } { "key": "HIGH", "value": 2 } $ cat input.json | jq -c '[. | to_entries[] | select(.key=="CRITICAL" or .key=="HIGH") | .value] | add' 3 # データを変更 $ vi input2.json ~~~~ { "MEDIUM": 3, "LOW": 4, "UNTRIGED": 5 } ~~~~ $ cat input2.json | jq -e '[. | to_entries[] | select(.key=="CRITICAL" or .key=="HIGH") | .value] | add' null # 代替演算子(//) $ cat input.json | jq -e '[. | to_entries[] | select(.key=="CRITICAL" or .key=="HIGH") | .value] | add | . // 0' 3 # null の時は、0に置き換える $ cat input2.json | jq -e '[. | to_entries[] | select(.key=="CRITICAL" or .key=="HIGH") | .value] | add | . // 0' 0
https://orebibou.com/ja/home/201605/20160509_001/
代替演算子(//)
https://www.tohoho-web.com/ex/jq.html
x // y # x が false や null でなければ x、さもなくば y
例4:複雑なJSON
https://dk521123.hatenablog.com/entry/2023/06/12/000000
で扱ったJSONをパースする
コマンド例 (Windows)
# ex1 $ type sql.json | jq .[] | jq .CreateTable.name [ { "value": "new_table", "quote_style": null } ] # ex2 $ type sql.json | jq .[] | jq .CreateTable.name[].value "new_table" # ex3 $ type sql.json | jq .[] | jq -r .CreateTable.name[].value new_table
[ { "CreateTable": { "or_replace": false, "temporary": false, "external": false, "global": null, "if_not_exists": false, "transient": false, "name": [ { "value": "new_table", "quote_style": null } ], "columns": [], "constraints": [], "hive_distribution": "NONE", "hive_formats": { "row_format": null, "storage": null, "location": null }, "table_properties": [], "with_options": [], "file_format": null, "location": null, "query": { "with": null, "body": { "Select": { "distinct": null, "top": null, "projection": [ { "UnnamedExpr": { "CompoundIdentifier": [ { "value": "t1", "quote_style": null }, { "value": "id", "quote_style": null } ] } }, { "UnnamedExpr": { "CompoundIdentifier": [ { "value": "t1", "quote_style": null }, { "value": "code", "quote_style": null } ] } }, { "UnnamedExpr": { "CompoundIdentifier": [ { "value": "t2", "quote_style": null }, { "value": "name", "quote_style": null } ] } } ], "into": null, "from": [ { "relation": { "Table": { "name": [ { "value": "table_1", "quote_style": null } ], "alias": { "name": { "value": "t1", "quote_style": null }, "columns": [] }, "args": null, "with_hints": [] } }, "joins": [ { "relation": { "Table": { "name": [ { "value": "table_2", "quote_style": null } ], "alias": { "name": { "value": "t2", "quote_style": null }, "columns": [] }, "args": null, "with_hints": [] } }, "join_operator": { "LeftOuter": { "On": { "BinaryOp": { "left": { "CompoundIdentifier": [ { "value": "t2", "quote_style": null }, { "value": "id", "quote_style": null } ] }, "op": "Eq", "right": { "CompoundIdentifier": [ { "value": "t1", "quote_style": null }, { "value": "id", "quote_style": null } ] } } } } } } ] } ], "lateral_views": [], "selection": { "BinaryOp": { "left": { "CompoundIdentifier": [ { "value": "t1", "quote_style": null }, { "value": "code", "quote_style": null } ] }, "op": "Eq", "right": { "Value": { "SingleQuotedString": "x0001" } } } }, "group_by": [], "cluster_by": [], "distribute_by": [], "sort_by": [], "having": null, "named_window": [], "qualify": null } }, "order_by": [], "limit": null, "offset": null, "fetch": null, "locks": [] }, "without_rowid": false, "like": null, "clone": null, "engine": null, "default_charset": null, "collation": null, "on_commit": null, "on_cluster": null, "order_by": null } } ]
参考文献
https://qiita.com/Nakau/items/272bfd00b7a83d162e3a
https://www.setouchino.cloud/blogs/19
https://www.wakuwakubank.com/posts/676-linux-jq/
https://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af
関連記事
CodeBuild で パラメータストア / Secrets Manager を使う
https://dk521123.hatenablog.com/entry/2020/02/18/230358
機密データの管理 ~ Secrets Manager 編 ~
https://dk521123.hatenablog.com/entry/2020/03/12/220717
AWS CLI ~ --query / JMESPath ~
https://dk521123.hatenablog.com/entry/2024/01/07/000000