ようへいの日々精進XP

よかろうもん

jq を使わないで Python や Ruby だけで JSON から任意のキーの値を取り出す苦肉の策

jq のありがたみを感じる今日此の頃。

以下のような...

test.json があるとする。(consul の service 情報を取得した際の出力結果)

[
    {
        "Address": "192.168.10.2",
        "Node": "node01",
        "ServiceID": "oreno-service",
        "ServiceName": "oreno-service",
        "ServicePort": 8888,
        "ServiceTags": null
    },
    {
        "Address": "192.168.10.3",
        "Node": "node02",
        "ServiceID": "oreno-service",
        "ServiceName": "oreno-service",
        "ServicePort": 8888,
        "ServiceTags": null
    }
]

Python でやってみる

以下のような Python スクリプトを用意する。

import json, sys

f = open('test.json', 'r')
j=json.load(f)

print len(j)

for attr in j:
    print attr.get('Node')

実行すると...

% python test.py
2
node01
node02

Node 数だけが欲しい場合のワンライナーにすると...

cat test.json| python -c "exec(\"import json,sys\\nj=json.load(sys.stdin)\\nprint len(j)\")"

Node の数と Node の値まで欲しい場合は...

cat test.json| python -c "exec(\"import json,sys\\nj=json.load(sys.stdin)\\nprint len(j)\\nfor attr in j:\\n    print attr.get('Node')\")"

Ruby でやってみる

Ruby の場合に標準入力を STDIN 定数の get メソッドread メソッドで読み込むことが出来る。get は一行毎、read は全体を読み込む。

cat hoge.json | ruby -r json -e 'j = STDIN.read; puts JSON.parse(j)'

以下のように出力される。

{"Address"=>"192.168.10.2", "Node"=>"node01", "ServiceID"=>"oreno-service", "ServiceName"=>"oreno-service", "ServicePort"=>8888, "ServiceTags"=>nil}
{"Address"=>"192.168.10.3", "Node"=>"node01", "ServiceID"=>"oreno-service", "ServiceName"=>"oreno-service", "ServicePort"=>8888, "ServiceTags"=>nil}

レコード数や任意のキーの値だけ取り出したい場合には...

cat hoge.json | ruby -r json -e 'r = STDIN.read;j = JSON.parse(r);puts j.count; j.each {|r| puts r["Node"]}'

以下のように出力される

2
node01
node02

あくまでも苦肉の策

jq をどうしてもインストール出来ない場合、今更インストールさせてくださいと言えない場合の苦肉の策メモでした。