无法从json键值响应解析键的值

时间:2019-11-04 22:08:46

标签: shell awk jq yq

团队,

我在下面有输出和json查询,但是无法检索mode旁边的值。

kubectl get configmap -n kube-system kube-proxy -o json | jq .data

{
  "config.conf": "apiVersion: kubeproxy.config.k8s.io/v1alpha1\nbindAddress: 0.0.0.0\nclientConnection:\n  acceptContentTypes: \"\"\n  burst: 10\n  contentType: application/vnd.kubernetes.protobuf\n  kubeconfig: /var/lib/kube-proxy/kubeconfig.conf\n  qps: 5\nclusterCIDR: 10.233.64.0/18\nconfigSyncPeriod: 15m0s\nconntrack:\n  max: null\n  maxPerCore: 32768\n  min: 131072\n  tcpCloseWaitTimeout: 1h0m0s\n  tcpEstablishedTimeout: 24h0m0s\nenableProfiling: false\nhealthzBindAddress: 0.0.0.0:10256\nhostnameOverride: hosta\niptables:\n  masqueradeAll: false\n  masqueradeBit: 14\n  minSyncPeriod: 0s\n  syncPeriod: 30s\nipvs:\n  excludeCIDRs: null\n  minSyncPeriod: 0s\n  scheduler: rr\n  syncPeriod: 30s\nkind: KubeProxyConfiguration\nmetricsBindAddress: 127.0.0.1:10249\nmode: iptables\nnodePortAddresses: []\noomScoreAdj: -999\nportRange: \"\"\nresourceContainer: /kube-proxy\nudpIdleTimeout: 250ms",
  "kubeconfig.conf": "apiVersion: v1\nkind: Config\nclusters:\n- cluster:\n    certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt\n    server: https://127.0.0.1:6443\n  name: default\ncontexts:\n- context:\n    cluster: default\n    namespace: default\n    user: default\n  name: default\ncurrent-context: default\nusers:\n- name: default\n  user:\n    tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token"
}
kubectl get configmap -n kube-system kube-proxy -o json | jq .data.\"config.conf\".mode
jq: error (at <stdin>:19): Cannot index string with string "mode"

还有,有没有办法使用awk来拉动它?

尝试:

kubectl get configmap -n kube-system kube-proxy -o json | jq -r '.["config.conf"] | splits("\n") | select( test("^mode") ) | [splits(": *")] | .[1]'
jq: error (at <stdin>:19): null (null) cannot be matched, as it is not a string

5 个答案:

答案 0 :(得分:3)

这是仅jq的解决方案:

.data
| .["config.conf"]
| splits("\n")
| select( test("^mode") )
| [splits(": *")]
| .[1]

使用-r命令行选项的结果:

iptables

-f选项

考虑使用jq的-f命令行选项或创建可执行脚本,而不是与shell进行斗争。

答案 1 :(得分:0)

通过使用jq -r .data.\"config.conf\",您可以获得config.conf的原始内容,然后可以轻松地grep或其他任何东西,它们不是json。

答案 2 :(得分:0)

没有JSON感知工具,解决方案将非常困难,否则将变得非常棘手。如果您要查找后一种类别的东西,则别无所求:

sed 's/\\n/\
/g' | grep '^ *mode:' | sed 's/ *mode: *//'

答案 3 :(得分:0)

在awk中尽可能强大地做到这一点将是(使用GNU awk将第三个参数匹配()):

$ cat tst.awk
{
    file = ""
    delete f
}
match($0,/"([^"]+)"[^"]+"(.*)"/,a) {
    file = a[1]
    numTags = split(a[2],tagsVals,/\\n/)
    for (i=1; i<=numTags; i++) {
        tag = val = tagsVals[i]
        gsub(/^\s+|\s*:.*/,"",tag)
        gsub(/^[^:]+:\s*|\s+$/,"",val)
        f[tag] = val
    }
}
(tgtFile == file) && (tgtVal in f) { print f[tgtVal] }

$ awk -v tgtFile='config.conf' -v tgtVal='mode' -f tst.awk file
iptables

$ awk -v tgtFile='config.conf' -v tgtVal='contentType' -f tst.awk file
application/vnd.kubernetes.protobuf

您只需要弄清楚如何处理数据中的重复标签(如“ name”)。如果您想获得这些值,似乎文件中可能需要处理第三级层次结构。

答案 4 :(得分:0)

我解决了jq和yq组合

kubectl get configmap -n kube-system kube-proxy -o json | jq -r '.data."config.conf" ' | yq '.mode'

输出:

"iptables"