json を jq で処理しているときに、期待しているキーがなくエラーになることがよくある。そのときの対処方法のメモ。
例えば、以下のコマンドを実行すると途中でエラーになる。
$ kubectl get clusterrole -o json | jq -r '.items[].rules[].apiGroups[]' cert-manager.io acme.cert-manager.io cert-manager.io acme.cert-manager.io (省略) authorization.k8s.io rbac.authorization.k8s.io * jq: error (at <stdin>:11356): Cannot iterate over null (null)
これは nonResourceURLs
では apiGroups
というキーがなくnull
が返されているのに []
でイテレーションしようとしているため。
対処方法 1
簡単な方法として []?
とすることで null
を無視できる。
$ kubectl get clusterrole -o json | jq -r '.items[].rules[].apiGroups[]?' cert-manager.io acme.cert-manager.io cert-manager.io acme.cert-manager.io (省略)
対処方法 2
目的のキーがあるかをチェックしてそれだけを select する。
$ kubectl get clusterrole -o json | jq -r '.items[].rules[] | select(has("apiGroups")) | .apiGroups[]' cert-manager.io acme.cert-manager.io cert-manager.io acme.cert-manager.io (省略)
map(x)
は [.[] | x]
と同じなので、以下のようにも記載できる。
$ kubectl get clusterrole -o json | jq -r '.items[].rules | map(select(has("apiGroups"))) | .[].apiGroups[]' cert-manager.io acme.cert-manager.io cert-manager.io acme.cert-manager.io (省略)