目的
JSON形式によって階層化されたテキストデータ構造をkey-value形式で表す。
# 個人的にJSON形式のデータを1ラインごとに見てみたいなと思って...
以下、入力になるJSON形式のデータと期待する出力結果。
{
"links": {
"self": "http://localhost:35357/v3/projects",
"previous": null,
"next": null
},
"projects": [
{
"is_domain": false,
"description": "Bootstrap project for initializing the cloud.",
"links": {
"self": "http://localhost:35357/v3/projects/27e8446cfa4240ae98fc70797a16739c"
},
"enabled": true,
"id": "27e8446cfa4240ae98fc70797a16739c",
"parent_id": "default",
"domain_id": "default",
"name": "admin"
},
{
"is_domain": false,
"description": "Service Project",
"links": {
"self": "http://localhost:35357/v3/projects/9e1eb34a5d4e45ee9ba95421d6f94548"
},
"enabled": true,
"id": "9e1eb34a5d4e45ee9ba95421d6f94548",
"parent_id": "default",
"domain_id": "default",
"name": "service"
}
]
}
links.self=http://localhost:35357/v3/projects
projects.0.description=Bootstrap project for initializing the cloud.
projects.0.links.self=http://localhost:35357/v3/projects/27e8446cfa4240ae98fc70797a16739c
projects.0.enabled=true
projects.0.id=27e8446cfa4240ae98fc70797a16739c
projects.0.parent_id=default
projects.0.domain_id=default
projects.0.name=admin
projects.1.description=Service Project
projects.1.links.self=http://localhost:35357/v3/projects/9e1eb34a5d4e45ee9ba95421d6f94548
projects.1.enabled=true
projects.1.id=9e1eb34a5d4e45ee9ba95421d6f94548
projects.1.parent_id=default
projects.1.domain_id=default
projects.1.name=service
実行環境
LinuxディストリビューションのCentOS7環境下にて検証する。
$ cat /etc/centos-release
CentOS Linux release 7.5.1804 (Core)
また、jqコマンドのバージョンは下記のとおり。
$ jq --version
jq-1.5
入力データとなるjson形式のファイルをtest.json
とする。
# 内容は前述したものと同様
{
"links": {
"self": "http://localhost:35357/v3/projects",
"previous": null,
"next": null
},
"projects": [
{
"is_domain": false,
"description": "Bootstrap project for initializing the cloud.",
"links": {
"self": "http://localhost:35357/v3/projects/27e8446cfa4240ae98fc70797a16739c"
},
"enabled": true,
"id": "27e8446cfa4240ae98fc70797a16739c",
"parent_id": "default",
"domain_id": "default",
"name": "admin"
},
{
"is_domain": false,
"description": "Service Project",
"links": {
"self": "http://localhost:35357/v3/projects/9e1eb34a5d4e45ee9ba95421d6f94548"
},
"enabled": true,
"id": "9e1eb34a5d4e45ee9ba95421d6f94548",
"parent_id": "default",
"domain_id": "default",
"name": "service"
}
]
}
key-value形式に変換(コマンド実行)
jqコマンドのマニュアルに記載してあるが、pathsとgetpath組み込み関数を使用することで実現可能。
# leaf_pathsは廃止予定らしいので使用していません
詳細はオフィシャルのマニュアルページやオンラインマニュアルをご参照ください。
$ cat test.json | jq -r 'paths(scalars)|@csv'
"links","self"
"projects",0,"description"
"projects",0,"links","self"
"projects",0,"enabled"
"projects",0,"id"
"projects",0,"parent_id"
"projects",0,"domain_id"
"projects",0,"name"
"projects",1,"description"
"projects",1,"links","self"
"projects",1,"enabled"
"projects",1,"id"
"projects",1,"parent_id"
"projects",1,"domain_id"
"projects",1,"name"
$ cat test.json | jq -r 'getpath(paths(scalars))'
http://localhost:35357/v3/projects
Bootstrap project for initializing the cloud.
http://localhost:35357/v3/projects/27e8446cfa4240ae98fc70797a16739c
true
27e8446cfa4240ae98fc70797a16739c
default
default
admin
Service Project
http://localhost:35357/v3/projects/9e1eb34a5d4e45ee9ba95421d6f94548
true
9e1eb34a5d4e45ee9ba95421d6f94548
default
default
service
上記のコマンド結果では、keyとvalueが一致しているかわからないので、同時に処理されるように工夫する。
$ cat test.json | jq -r 'paths(scalars) as $path | ($path | @csv | tostring) + "=" + (getpath($path) | tostring)'
"links","self"=http://localhost:35357/v3/projects
"projects",0,"description"=Bootstrap project for initializing the cloud.
"projects",0,"links","self"=http://localhost:35357/v3/projects/27e8446cfa4240ae98fc70797a16739c
"projects",0,"enabled"=true
"projects",0,"id"=27e8446cfa4240ae98fc70797a16739c
"projects",0,"parent_id"=default
"projects",0,"domain_id"=default
"projects",0,"name"=admin
"projects",1,"description"=Service Project
"projects",1,"links","self"=http://localhost:35357/v3/projects/9e1eb34a5d4e45ee9ba95421d6f94548
"projects",1,"enabled"=true
"projects",1,"id"=9e1eb34a5d4e45ee9ba95421d6f94548
"projects",1,"parent_id"=default
"projects",1,"domain_id"=default
"projects",1,"name"=service
ポイントは "パスを変数に格納", "文字列に変換", "文字列の結合" をすること。
階層の連結を表す記号(上記の場合カンマ",")を変更したり、ダブルクォートを除去したい場合は、次のコマンドを実行する。
$ cat test.json | jq -r 'paths(scalars) as $path | ($path | @csv | tostring | gsub(
","; ".") | gsub("\""; "")) + "=" + (getpath($path) | tostring)'
links.self=http://localhost:35357/v3/projects
projects.0.description=Bootstrap project for initializing the cloud.
projects.0.links.self=http://localhost:35357/v3/projects/27e8446cfa4240ae98fc70797a16739c
projects.0.enabled=true
projects.0.id=27e8446cfa4240ae98fc70797a16739c
projects.0.parent_id=default
projects.0.domain_id=default
projects.0.name=admin
projects.1.description=Service Project
projects.1.links.self=http://localhost:35357/v3/projects/9e1eb34a5d4e45ee9ba95421d6f94548
projects.1.enabled=true
projects.1.id=9e1eb34a5d4e45ee9ba95421d6f94548
projects.1.parent_id=default
projects.1.domain_id=default
projects.1.name=service
階層の連結記号を外部変数から参照したいなら--arg
オプションをつければ実現可能。
$ cat test.json | jq -r --arg conn "-->" 'paths(scalars) as $path | ($path | @csv | tostring | gsub(
","; $conn) | gsub("\""; "")) + "=" + (getpath($path) | tostring)'
projects-->0-->description=Bootstrap project for initializing the cloud.
projects-->0-->links-->self=http://localhost:35357/v3/projects/27e8446cfa4240ae98fc70797a16739c
projects-->0-->enabled=true
projects-->0-->id=27e8446cfa4240ae98fc70797a16739c
projects-->0-->parent_id=default
projects-->0-->domain_id=default
projects-->0-->name=admin
projects-->1-->description=Service Project
projects-->1-->links-->self=http://localhost:35357/v3/projects/9e1eb34a5d4e45ee9ba95421d6f94548
projects-->1-->enabled=true
projects-->1-->id=9e1eb34a5d4e45ee9ba95421d6f94548
projects-->1-->parent_id=default
projects-->1-->domain_id=default
projects-->1-->name=service
おわりに
うまいことkey-value形式に変換できているように見えるが、valueがnullになっているパスは表示されていません。
null値も表示させたいけど今のところわからないので、表示のさせ方がわかったら追記しときます。