2017/10/07

jqコマンド

最近、JSON-RPCで指示を出して、その結果を取得するようなプログラムを作った。
ネットでよくある、JSON整形してくれるページで結果を確認したので、まあ間違ってはいないようだ。


JSON形式は、あまりお好きではない。
理由は、コンマだ・・・。

最後のデータにコンマを許可しないというルール故に、出力するときはひどく面倒なのだ。
まず、1行目の先頭にコンマがあってはならないので、1行目は普通に出力する。
2行目があるなら、コンマを出力してから2行目を出力することになる。
そして、それを繰り返していき、最後のデータの場合はコンマ無しで終わらせる。


順番にデータを掃き出すときはそこまで困らないのだが、嫌なのはforなどでぐるぐると掃き出したい場合だ。
コンマを出力する処理を、行の出力を行う前に置くか、後に置くか。。。
前に置くと、1行目だけコンマ出力をスキップする、という処理がいるし、後に置くと「次のデータがあるか」をチェックする処理がいる。
それが嫌だったら、1行目の出力と2行目以降の出力を分け、forですぐにコンマ出力するようにしておけばよいが、コンマのためだけに処理を分けるのも腹立たしい。

最後のデータにコンマを許可するか、あるいはコンマを無くしてしまう構造だったら悩まなくて済むと思うのだ。
まあ、データ構造に文句を言っても仕方ないのだが・・・。


JSON形式で出力するのが面倒であることを書きたいだけの記事なのだが、それだけでは何なのでjqコマンドのことを書こう。

Ubuntuではapt-getでinstallすることになるが、jqというJSON形式のデータを整形したり加工したりできるコマンドがある。
非常に多機能なのだが、自作で掃き出したJSON形式の改行やスペースが見づらかったとしても、引数無しでjqコマンドを通すだけで見やすくなる。

$ ./cli/lightning-cli getinfo
{ "id" : "02d030cf51591116155597cee2cbf8bb432fa01b691c055d329b51c838fd754130", "port" : 9735, "network" : "testnet", "version" : "v0.5.2-2016-11-21-964-geedbd1d", "blockheight" : 1209621 }


$ ./cli/lightning-cli getinfo | jq
{
   "id": "02d030cf51591116155597cee2cbf8bb432fa01b691c055d329b51c838fd754130",
   "port": 9735,
   "network": "testnet",
   "version": "v0.5.2-2016-11-21-964-geedbd1d",
   "blockheight": 1209621
}

ほら、この通り!
カラーが使えるコンソールであれば、パラメータとデータで色分けもしてくれるし、データも数値か文字列かで色が変わってくれるので、見やすい。


いま見ているgithubのサイトで、よくわからない使い方をしているので、なにやっているのか見ておきたい。

https://github.com/ElementsProject/lightning#receiving-and-receiving-payments

route=$(cli/lightning-cli getroute <recipient_id> <amount> 1 | jq --raw-output .route -)

cli/lightning-cliコマンドが何を出力するのかはあまり関係ないのだが、例がないと分かりづらいので載せておこう。

{ "route" :
         [
                 { "id" : "aaa", "channel" : "1207790:27:0", "msatoshi" : 101023561, "delay" : 92 },
                 { "id" : "bbb", "channel" : "1207703:21:0", "msatoshi" : 100511006, "delay" : 56 },
                 { "id" : "ccc", "channel" : "1207785:11:0", "msatoshi" : 100001001, "delay" : 46 },
                 { "id" : "ddd", "channel" : "1207779:2:0", "msatoshi" : 100000000, "delay" : 36 } ] }

コマンドの1行としては、「route=$(中身)」が外側で、その中身がjqの結果になるのだと思う。
では、cli/lightning-cliコマンドが出力した内容をjj.txtというファイルに保存したとすると、こうなるはず。
青文字が結果だ。

$ cat jj.txt | jq --raw-output .route-
[
   {
     "id": "aaa",
     "channel": "1207790:27:0",
     "msatoshi": 101023561,
     "delay": 92
   },
   {
     "id": "bbb",
     "channel": "1207703:21:0",
     "msatoshi": 100511006,
     "delay": 56
   },
   {
     "id": "ccc",
     "channel": "1207785:11:0",
     "msatoshi": 100001001,
     "delay": 46
   },
   {
     "id": "ddd",
     "channel": "1207779:2:0",
     "msatoshi": 100000000,
     "delay": 36
   }
]

「route」要素だけを出力したことになるのかな?
ただ、これを環境変数?に代入して、echoなどで掃き出しても、改行が残らないのだ。

$ route=$(cat jj.txt | jq --raw-output .route -)
$ echo $route
[ { "id": "aaa", "channel": "1207790:27:0", "msatoshi": 101023561, "delay": 92 }, { "id": "bbb", "channel": "1207703:21:0", "msatoshi": 100511006, "delay": 56 }, { "id": "ccc", "channel": "1207785:11:0", "msatoshi": 100001001, "delay": 46 }, { "id": "ddd", "channel": "1207779:2:0", "msatoshi": 100000000, "delay": 36 } ]

最後のハイフンがそういう意味なのかと思ったけど、ハイフンを外しても結果が変わらんかった。
tarコマンドで、標準出力とか標準入力とかを使うときにハイフンを付けるのと同じ意味のように思う。
じゃあ、パイプじゃなくてもいいやん、というか、パイプで書いているからハイフンがなくても動いているのかもしれん。


とにかく、何が言いたかったかというと、バイナリデータ最高!、ということでした。。。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。