jq: ошибка: синтаксическая ошибка, неожиданная, если при проверке наличия объекта и если нет добавляемого значения по умолчанию

#json #shell #kubernetes #jq #kubectl

Вопрос:

Получение ошибки

 jq: error: syntax error, unexpected if (Unix shell quoting issues?) at <top-level> while parsing kubernetes kubectl command,
kubectl get pv -o=json | jq -c '.items[] | {name: .metadata.name, claimName: .spec | if has("claimRef") then .claimRef.name else empty end }'
 

Попытка получить фотоэлектрические элементы, в которых есть ПВХ, и если ПВХ нет, может быть пустой.
Для этого необходимо указать карту имен и их соответствующие значения, если в противном случае они пусты или пусты.

Ниже приведен пример ввода команды jq или вывода команды kubectl get pv -o=json

 {
    "apiVersion": "v1",
    "items": [{
            "apiVersion": "v1",
            "kind": "PersistentVolume",
            "metadata": {
                "annotations": {
                    "meta.helm.sh/release-name": "",
                    "meta.helm.sh/release-namespace": ""
                },
                "creationTimestamp": "",
                "finalizers": [
                    ""
                ],
                "labels": {
                    "app.kubernetes.io/managed-by": ""
                },
                "name": "",
                "resourceVersion": "",
                "uid": ""
            },
            "spec": {
                "accessModes": [
                    "ReadWriteMany"
                ],
                "capacity": {
                    "storage": ""
                },
                "claimRef": {
                    "apiVersion": "",
                    "kind": "",
                    "name": "",
                    "namespace": "",
                    "resourceVersion": "",
                    "uid": ""
                },
                "csi": {
                    "driver": "",
                    "volumeHandle": ""
                },
                "persistentVolumeReclaimPolicy": "",
                "volumeMode": ""
            },
            "status": {
                "phase": ""
            }
        },
        {
            "apiVersion": "v1",
            "kind": "PersistentVolume",
            "metadata": {
                "annotations": {
                    "meta.helm.sh/release-name": "",
                    "meta.helm.sh/release-namespace": ""
                },
                "creationTimestamp": "",
                "finalizers": [
                    ""
                ],
                "labels": {
                    "app.kubernetes.io/managed-by": ""
                },
                "name": "",
                "resourceVersion": "",
                "uid": ""
            },
            "spec": {
                "accessModes": [
                    "ReadWriteMany"
                ],
                "capacity": {
                    "storage": ""
                },
                "claimRef": {
                    "apiVersion": "",
                    "kind": "",
                    "name": "",
                    "namespace": "",
                    "resourceVersion": "",
                    "uid": ""
                },
                "csi": {
                    "driver": "",
                    "volumeHandle": ""
                },
                "persistentVolumeReclaimPolicy": "",
                "volumeMode": ""
            },
            "status": {
                "phase": ""
            }
        }
    ],
    "kind": "List",
    "metadata": {
        "resourceVersion": "",
        "selfLink": ""
    }
}
 

Для безопасности данных удалили данные и сохранили только ключи
Пожалуйста, помогите

Ответ №1:

Заключите значение claimName поля в круглые скобки:

 {
  name: .metadata.name,
  claimName: (.spec | if has("claimRef") then .claimRef.name else empty end)
}
 

В зависимости от того, насколько вы упростили свой пример, вы можете рассмотреть возможность сокращения if оператора до:

 {
  name: .metadata.name,
  claimName: (.spec.claimRef.name? // empty)
}
 

Обратите внимание, что в обоих случаях не только .claimName , но и весь объект исчезнет, если соответствующий тест завершится неудачей.

Комментарии:

1. Спасибо @pmf за решение, которое работает сейчас. Как может быть пустой объект в имени утверждения, если .spec.claimRef там нет.

2. Сделайте else ветвь, как вы говорите, «пустым объектом», который является {} : {name: .metadata.name} (.spec | if has("claimRef") then {claimName: .claimRef.name} else {} end) .

3. Отлично @pmf, это все решает, спасибо