У меня есть такой json-файл, мне бы хотелось иметь решение на основе jq
для его преобразования:
{
... fields1 ...
"any": [], "other": 1,
"aa.2": "second.", "aa.1": "first ",
... fields2 ...
"bla.bla.0": "aa", "bla.bla.2": "bb",
... fields3 ...
}
Я хочу, чтобы выходные данные были сгруппированы по префиксу перед «.<номер>», объединенному в строку (значения для них можно считать строками). Порядок полей с окончанием «.<номер>» не обязательно является упорядоченным. поля1,2,3 – другие поля, которые необходимо сохранить (порядок полей в выходном объекте сохранять не обязательно) Поля с окончанием «.<номер>» должны быть удалены из вывода, должно быть сохранено только объединенное конечное значение.
{
... fields1 ...
"any": [], "other": 1,
"aa": "first second.",
... fields2 ...
"bla.bla": "aabb",
... fields3 ...
}
Я пытался найти решение с помощью инструкции, но мне это не удалось.
Вы ищете что-то вроде этого:
"(?<prefix>.*)\\.(?<order>\\d+)$" as $pat
| to_entries
| (map(select(.key | test($pat) | not)) | from_entries)
+ (map({value} + (.key | capture($pat)))
| group_by(.prefix)
| map(sort_by(.order | tonumber) | {(.[0].prefix): map(.value) | add})
| add)
Вы можете разрезать по положению последней точки rindex(".")
, чтобы найти будущий ключ и части числа, а затем reduce
по группам, чтобы итеративно построить объект результата. Значения можно получить путем сортировки преобразованной части числа tonumber
.
reduce (to_entries | group_by(.key | .[:rindex(".")])[]) as $g ({};
($g[0].key | rindex(".")) as $p | .[$g[0].key[:$p]] = if $p
then $g | sort_by(.key |= (.[$p+1:] | tonumber)) | map(.value) | add
else $g[0].value end
)
{
"a": "...field_a...",
"aa": "first second.",
"b": "...field_b...",
"bla.bla": "aabb",
"c": "...field_c..."
}
Грасиас, точно.