jqfpyにchunkを追加した。直接batch requestを叩けるように(続く)。

github.com

jqfpyにchunkを追加した。直接batch requestを叩けるように。ただまだ機能は不足しているような気がする。試しにelastic searchのbatch apiを叩いてみようと思ったけれど。まだ足りなそうな感じ(続く)。

欲しくなった理由

例えばテキトウなJSONを出力するコードがあるとする。正確には、データができ次第標準出力にJSONを出力するようなコード。 そのような出力は--slurp付きで呼び出すと、jqfpy上では1つの配列として扱うことができる。

$ seq 1 10
1
2
3
4
5
6
7
8
9
10

$ seq 1 10 | jqfpy --slurp -c
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

これに加えて利用するデータが大きすぎる場合に適宜細かい単位に区切ってあれこれしたい。そのための機能。

h.chunk()

h.chunkは以下の様な感じ。

$ seq 1 10 | jqfpy --slurp -c 'h.chunk(get(), n=3)'
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

3つごとに取り出してみている。(n=3はkeyword only argumentsなのだけれど。制限を緩めたほうが使いやすいかもしれない。h.chunk(L, 3)と書けるように)

1行毎のchunked JSON

ちなみに --squash-c を組み合わせると、1行毎にN個ずつまとめられたJSONが返るようになるので便利。

$ seq 1 10 | jqfpy --slurp -c 'h.chunk(get(), n=3)' --squash
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[10]

例えば、xargsと一緒に使ってみる。

$ seq 1 10 | jqfpy --slurp -c 'h.chunk(get(), n=3)' --squash | xargs -I{} echo get data -- {}  --.
get data -- [1, 2, 3] --.
get data -- [4, 5, 6] --.
get data -- [7, 8, 9] --.
get data -- [10] --.

あるいは、bashでループする。

$ seq 1 10 | jqfpy --slurp -c 'h.chunk(get(), n=3)' --squash | (while read LINE; do echo got: $LINE; done)
got: [1, 2, 3]
got: [4, 5, 6]
got: [7, 8, 9]
got: [10]

連番を振りたい場合があるかも?

連番を振りたい場合があるかも?ちょっと複雑な何かを作りたい時に一時的にファイルに書き出したいということはある。

これにはまだちょっと対応できない。空でbashのループを書くのもだるいし。何か良い方法は見つけたい。

一応、暫定的な処置としては以下の様な形でbashの範囲で無理やり書くという方法はある。

$ seq 1 10 | jqfpy --slurp -c 'h.chunk(get(), n=3)' --squash | (i=0; while read LINE; do i=$(($i + 1)); echo "got($i): $LINE"; done)
got(1): [1, 2, 3]
got(2): [4, 5, 6]
got(3): [7, 8, 9]
got(4): [10]

例えば、こういう感じに。

$ seq 1 10 | jqfpy --slurp -c 'h.chunk(get(), n=3)' --squash | (i=0; while read LINE; do i=$(($i + 1)); echo $LINE | jqfpy > data$i.json; done)

$ ls
data1.json  data2.json  data3.json  data4.json

$ cat data1.json
[
  1,
  2,
  3
]

細かい話をすると

細かい話をすると、--slurpと一緒に--unbufferedを使うことには対応していないので、一度すべてのデータを集めてからchunkするという形になっている。なので処理が終わらないとフィルタとしてのjqfpyは実行されないし。省メモリーでもない。