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

元記事はこちら

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