невозможно проанализировать значение ключа из ответа значения ключа json

Команда,

У меня ниже вывод и 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

5 ответов

Решение

Вот решение только для jq:

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

Результат с использованием параметра командной строки -r:

iptables

-f опция

Вместо того, чтобы сражаться с вашей оболочкой, рассмотрите возможность использования параметра командной строки -f для jq или создания исполняемого скрипта.

Я решил с ним комбинации jq и yq

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

выход:

"iptables"

Без инструмента, поддерживающего JSON, решение будет довольно сложным или очень хакерским. Если вы ищете что-то из последней категории, вам не нужно идти дальше:

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

Чтобы сделать это как можно более надежно в awk (используя GNU awk для третьего аргумента match()):

$ 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" в данных. Похоже, что в вашем файле может быть третий уровень иерархии, с которым вам нужно будет работать, если вы хотите получить эти значения.

Используя jq -r .data.\"config.conf\" вы получаете сырое содержимое config.conf, которые вы затем можете легко использовать grep или что-то еще, они не json.

Другие вопросы по тегам