Search code examples
jsonjq

Using jq to group-concat fields by field name prefix


I have a json file like this, I woiuld like to have a jq based solution to transform this:

{
   ... fields1 ...
   "any": [], "other": 1,
   "aa.2": "second.", "aa.1": "first ",
   ... fields2 ...
   "bla.bla.0": "aa", "bla.bla.2": "bb",
   ... fields3 ...
}

I want an output grouped by prefix before ".<number>" concatenated as string (values for those can be assumed to be strings). The order of the fields with ".<number>" ending is not necessarily ordered. fields1,2,3 are other fields need to be kept (the order of the fields in the output object do not have to be kept) The fields with ".<number>" ending must be removed in the output, only the concatenated final value is to be kept.

{
   ... fields1 ...
   "any": [], "other": 1,
   "aa": "first second.",
   ... fields2 ...
   "bla.bla": "aabb",
   ... fields3 ...
}

I tried to find a solution using the manual but I did not succeed.


Solution

  • You're looking for something like this:

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