jqが難しい

例えば以下のようなJSONから、以下のような条件で取り出した結果を出力したい

  • .appsのオブジェクトのkey名が辞書順で欲しい
  • ただし、useがfalseのものは含めないようにしたい

apps.json

{
  "apps": {
    "foo": {
      "use": false
    },
    "bar": {
      "use": true
    },
    "boo": {
      "use": true
    },
    "bee": {
      "use": true
    }
  }
}

以下のような出力。

bar
boo
bee

jqで上手くかけなかった

objectをiterateしつつuseがtrueのものを取り除くということができなかった。30分位いろいろ調べていたけれどだめだった。

pythonで(頑張れば)ワンライナーで書けるレベルなのに

pythonでも(なんとか)ワンライナーで書けるレベルの処理なのに結局jqでどう書けば良いかわからなかった。かなしい。

$ cat apps.json | python -c 'print("\n".join(sorted(k for k, v in __import__("json").load(__import__("sys").stdin)["apps"].items() if v["use"])))'
bar
boo
bee

ところで

普通は雑なスクリプト/tmp 以下に書くほうが良さそうな感じ。

# x.py
import json
import sys

d = json.load(sys.stdin)
buf = [k for k, v in d["apps"].items() if v["use"]]
print("\n".join(sorted(buf)))

普通に動くし1分くらいでかける。

$ cat /tmp/app.json | python /tmp/x.py
bar
boo
bee

とは言え、どこかファイルにコードを書かなくてはいけないという部分が苦痛に感じたりもする。

というより

jqがなぜつらいのかをもう少し真面目に考えてみる気になった。

jqが必要な理由は明らかで、何らかのJSON表現の内、全体が必要なことはまれで一部分だけを抽出したいあるいは一部構造を調整したい。これを行うためのglue部分としてシェル上からパイプでつなげるような何かが欲しい。