2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

jqコマンドでJSON形式をkey-value形式に変換

Posted at

目的

JSON形式によって階層化されたテキストデータ構造をkey-value形式で表す。
# 個人的にJSON形式のデータを1ラインごとに見てみたいなと思って...
以下、入力になるJSON形式のデータと期待する出力結果。

入力データ(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とする。
# 内容は前述したものと同様

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は廃止予定らしいので使用していません
詳細はオフィシャルのマニュアルページやオンラインマニュアルをご参照ください。

コマンド例1
$ 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"
コマンド例2
$ 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が一致しているかわからないので、同時に処理されるように工夫する。

コマンド例3
$ 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

ポイントは "パスを変数に格納", "文字列に変換", "文字列の結合" をすること。
階層の連結を表す記号(上記の場合カンマ",")を変更したり、ダブルクォートを除去したい場合は、次のコマンドを実行する。

コマンド例4
$ 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オプションをつければ実現可能。

コマンド例5
$ 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値も表示させたいけど今のところわからないので、表示のさせ方がわかったら追記しときます。

2
3
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?