ExtJS
Sencha
jq
SenchaArchitect

JSONデータのキー名をワンライナーでカンマ区切りで取得する

Sencha Architect で Ext JS の Model を設定する際は、使用するデータのフィールド名をカンマ区切りで指定するのが便利です。

licecap.gif

しかし、こういうのをキーボードから入力するのは微妙に面倒です。既存のJSONデータからコピペすれば手入力の手間は省けますが、項目数が多い場合はコピペするのも案外面倒です。

そこで、既存のJSONデータのキー名をカンマ区切りで取得するようなワンライナーを書いてみることにします。


ワンライナーの例

jq を使えばキーだけを容易に抜き出せますから、それをちょいと加工するだけです。

JSONデータのファイルを使うならこうですね。

cat jsondata.txt | jq -r '.(rootProperty)|keys|@csv' | sed 's/"//g'

ライブデータから作る場合は curl を使えばよいと思います。

curl -s [WebAPI] | jq -r '.(rootProperty)|keys|@csv' | sed 's/"//g'

(rootProperty) の部分は扱うデータにあわせて適切に変更してください。rootProperty が無い場合は単に . だけで良いはずです。

JSONデータが単純な配列ではなく、構造が入り組んでいる場合でも、参照したい部分を的確に指定すればキーは取得できます。

なお、ワンライナーの最後に sed で " を消す操作が自分的にはイマイチだと思っていますので、jq だけで " を落とす方法をご存知の方がいらっしゃいましたらコメント欄でフォローしていただけると大変ありがたいです。

2019/02/08追記

ワンライナーだけでも良いのですが、ふと気がつくと jq や sed のパラメータを忘れてしまうので、シェルスクリプトにすることにしました。

そしてせっかくなので、generateModelField.sh "ファイル名またはURL" "参照したい要素" のように実行できるように実装してみます。


generateModelField.sh

#!/bin/bash

file=$1
jsonpath=$2

(
if [ -e ${file} ]; then
cat ${file}
fi

if [ ${file:0:4} == "http" ]; then
curl -s ${file}
fi
) | jq -r "${jsonpath}|keys|@csv" | sed 's/"//g'



上記の結果に至る手順

とりあえず、環境は Ubuntu(WSL含む), macOS を想定しています。

使うコマンドは curl, jq, sed ですが、jq は未インストールのケースが多いと思いますので、この機会にインストールしてください。brew, apt でインストールできるはずです。

また、ここからの手順では主に jq を使っていますが、jq 自体の細かい使い方は解説しませんので、今回初めて jq を知った方はググってみてください。

まず、次のように実行すると、API の実行結果が jq で整形された形で取得できます。

$ curl -s http://apis.is/earthquake/is | jq '.' | more

{
"results": [
{
"timestamp": "2017-10-13T12:07:24.000Z",
"latitude": 63.976,
"longitude": -21.949,
"depth": 1.1,
"size": 0.6,
"quality": 58.73,
"humanReadableLocation": "6,1 km SV af Helgafelli"
},
.
.
.

このデータは rootProperty が "results" なので、jq のパラメータを以下のように書き換えれば、JSON配列の0番目だけが取り出せます。

$ curl -s http://apis.is/earthquake/is | jq '.results[0]'

{
"timestamp": "2017-10-13T12:07:24.000Z",
"latitude": 63.976,
"longitude": -21.949,
"depth": 1.1,
"size": 0.6,
"quality": 58.73,
"humanReadableLocation": "6,1 km SV af Helgafelli"
}

さらに jq のパラメータを次のように変えてみると、key だけが抜き出せました。

$ curl -s http://apis.is/earthquake/is | jq '.results[0]|keys'

[
"depth",
"humanReadableLocation",
"latitude",
"longitude",
"quality",
"size",
"timestamp"
]

この結果を csv 変換すれば、key のカンマ区切りが手に入るはずですが、これだけではうまくいきません。

$ curl -s http://apis.is/earthquake/is | jq '.results[0]|keys|@csv'

"\"depth\",\"humanReadableLocation\",\"latitude\",\"longitude\",\"quality\",\"size\",\"timestamp\""

そこで jq のコマンドラインパラメータに -r を追加してみます。


$ curl -s http://apis.is/earthquake/is | jq -r '.results[0]|keys|@csv'
"depth","humanReadableLocation","latitude","longitude","quality","size","timestamp

これで概ね欲しい結果になりましたが、" が邪魔なので消しましょう。今回は jq の出力結果から一括で " を落とすために sed でフィルタしてみます。

$ curl -s http://apis.is/earthquake/is | jq -r '.results[0]|keys|@csv' | sed 's/"//g'

depth,humanReadableLocation,latitude,longitude,quality,size,timestamp

これで目的の結果が得られました。