I'd like to transform a "raw" json data transforming to other json structure.
For example:
def template:
{
"id": "$id",
"practitioner": "$practitioner",
"patient": {
"name": "$patientName",
"familyName": "$patientFamilyName"
}
}
;
My data.json is:
[
{
"id": "id1",
"practitioner": {
"practitionerKey1": "practitionerValue1",
"practitionerKey2": "practitionerValue2"
},
"name": "John",
"familyName": "Smith"
},
{
"id": "id2",
"practitioner": {
"practitionerKey1": "practitionerValue1",
"practitionerKey2": "practitionerValue2"
},
"patientName": "Samuel",
"patientFamilyName": "Schnaider"
}
]
My desired result would be:
[
{
"id": "id1",
"practitioner": {
"practitionerKey1": "practitionerValue1",
"practitionerKey2": "practitionerValue2"
},
"patient": {
"name": "John",
"familyName": "Smith"
}
},
{
"id": "id2",
"practitioner": {
"practitionerKey1": "practitionerValue1",
"practitionerKey2": "practitionerValue2"
},
"patient": {
"name": "Samuel",
"familyName": "Schnaider"
}
}
]
Any ideas about how to map above data json and populate it using a json template with JQ?
CodePudding user response:
The "query-by-example" approach you envision in the question is do-able, though it is error-prone (and indeed as @pmf pointed out, your example contains an error). This is how to realize the "QBE" approach based on matching "$-names" with key names:
def matchName($name):
first(.. | objects | to_entries[] | select(.key == $name) | .value) // null ;
def fillin($t):
. as $in
| $t
| walk(if type == "string" and startswith("$")
then .[1:] as $s | $in | matchName($s)
else . end);
map(fillin(template))
CodePudding user response:
Disregarding your template, why not simply calling
jq 'map(
.patient = {name: .patientName, familyName: .patientFamilyName}
| del(.patientName, .patientFamilyName)
)' data.json
Demo (For this, I corrected your input JSON according to a presumed typo described in my comment above)