Использование jq для группировки полей по префиксу имени поля

У меня есть такой 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 ...
}

Я пытался найти решение с помощью инструкции, но мне это не удалось.

Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
1
0
53
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы ищете что-то вроде этого:

"(?<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)

Грасиас, точно.

Tamás Horváth 24.07.2024 10:30

Вы можете разрезать по положению последней точки 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..."
}

Демо

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