Я пытаюсь проверить все версии в файле versions.json
и получить в качестве вывода json только с неверными версиями.
Вот пример файла:
{
"slamx": "16.4.0 ",
"sdbe": null,
"mimir": null,
"thoth": null,
"quasar": null,
"connectors": {
"s3": "16.0.17",
"azure": "6.0.17",
"url": "8.0.2",
"mongo": "7.0.15"
}
}
Я могу использовать следующую строку сценария jq
, чтобы делать то, что я хочу:
delpaths([paths(type == "string" and contains(" ") or type == "object" | not)])
| delpaths([paths(type == "object" and (to_entries | length == 0))])
И используйте его на оболочке так:
BAD_VERSIONS=$(jq 'delpaths([paths(type == "string" and contains(" ") or type == "object" | not)]) | delpaths([paths(type == "object" and (to_entries | length == 0))])' versions.json)
if [[ $BAD_VERSIONS != "{}" ]]; then
echo >&2 $'Bad versions detected in versions.json:\n'"$BAD_VERSIONS"
exit 1
fi
и получите это как вывод:
Bad versions detected in versions.json:
{
"slamx": "16.4.0 "
}
Однако это очень запутанный способ фильтрации. Вместо того, чтобы просто пройтись по дереву путей и просто сказать «сохрани это, сохрани это», мне нужно создать список вещей, которые мне не нужны, и удалить их, дважды .
Учитывая все встроенные функции обработки пути и рекурсивную обработку, я не могу не чувствовать, что должен быть лучший способ сделать это, что-то похожее на select
, но рекурсивно работать по объекту, но лучше Я мог бы сделать это:
. as $input |
[path(recurse(.[]?)|select(strings|contains("16")))] as $paths |
reduce $paths[] as $x ({}; . | setpath($x; ($input | getpath($x))))
Мне это не нравится по двум причинам. Во-первых, я создаю новый объект вместо того, чтобы «редактировать» старый. Во-вторых, он полон переменных, что указывает на серьезную проблему инверсии потока и добавляет сложности.
Есть идеи?