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

unable to parse key's value from json key value response

团队,

我有以下输出和 json 查询,但无法检索模式旁边的值。

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

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

这是一个仅 jq 的解决方案:

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

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

iptables

-f选项

与其与你的 shell 斗争,不如考虑使用 jq 的 -f 命令行选项,或者创建一个可执行脚本。

如果没有 JSON-aware 工具,解决方案将非常困难或非常棘手。如果您正在寻找后一类的东西,您只需:

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

要在 awk 中尽可能稳健地执行此操作(使用 GNU awk 来匹配第三个参数()):

$ cat tst.awk
{
    file = ""
    delete f
}
match([=10=],/"([^"]+)"[^"]+"(.*)"/,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" 等重复标记。如果您想获得这些值,您的文件中似乎可能需要处理第三层层次结构。

我用它解决了 jq 和 yq 组合

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

输出:

"iptables"