Assuming that the fields are always in the given order, that there is a header line on the first line of input, and that multiple space characters delimit fields, you may compress the runs of consecutive spaces with tr
and parse the data with jq
.
database-client-command |
tr -s ' ' |
jq -c -Rn '
input | split(" ") as $head |
inputs | split(" ") |
to_entries |
map(.key = $head[.key]) |
[ .[:2][], { key: "DATA", value: (.[2:] | from_entries) } ] |
from_entries'
The jq
expression reads the raw data from tr
as separate lines.
The first line is split into the headers and stored into an array in $head
.
We split the remaining lines into arrays as we did with the header. The to_entries
filter converts each array into "entry form" (collections of objects with key
and value
keys), and the map()
replaces the numerical array indexes with the headers from $head
as keys.
After the map()
, the filter rearranges the array the third element on are moved down into a separate DATA
sub-object and converted back from "entry form".
When done with the keys and data rearrangement, the from_entries
filter returns the array from the "entry form".
The output of the script would be a set of JSON objects, and given the data in your question, these would look as follows.
{"CID":"12","CN":"2123","DATA":{"XY":"120.9","NAT":"29.0","UIC":"100.0","DATE":"2018-06-08","Region":"JAIPUR"}}
{"CID":"13","CN":"0987","DATA":{"XY":"78.9","NAT":"100.3","UIC":"28.8","DATE":"2020-12-09","Region":"DELHI"}}
If you want to change Region
into REGION
and DATE
into Date
, then consider doing this as you query the database or as a post-processing step.
Note that your expected result is not valid JSON due to the trailing comma on the first line.
DATE
toDate
andRegion
toREGION
then edit your question to explain the logic around which fields to select to change the case of. If you don't really want that then edit your question to fix your example.,
should be present at the end of the first row of expected output? That doesn't appear to be valid JSON.