skip to Main Content

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.

2

Answers


  1. 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) | join("")})
      | add)
    
    Login or Signup to reply.
  2. You can slice by the position of the last dot rindex(".") to find the future key and the number parts, then reduce by the groups to iteratively construct the result object. The values can be constructed by sorting the number part converted 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..."
    }
    

    Demo

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search