I have a bunch (hundreds) of JSON files with a parent child structure, e.g.
{
"tables": [
{
"name": "TableA",
"fields": [
{
"name": "FieldA"
},
{
"name": "FieldB"
}
]
},
{
"name": "TableB",
"fields": [
{
"name": "FieldA"
},
{
"name": "FieldB"
}
]
}
]
}
and I want to add an extra field to the child object containing a value from the parent, e.g.
{
"tables": [
{
"name": "TableA",
"fields": [
{
"name": "FieldA",
"fqn": "TableA_FieldA"
},
{
"name": "FieldB",
"fqn": "TableA_FieldB"
}
]
},
{
"name": "TableB",
"fields": [
{
"name": "FieldA",
"fqn": "TableB_FieldA"
},
{
"name": "FieldB",
"fqn": "TableB_FieldB"
}
]
}
]
}
Since there are so many files I'd like to process them automatically, and it feels like this should be doable with JQ, but I can't seem to work out how. Is anyone able to help?
CodePudding user response:
Use the update operator |=
to retain the contexts while storing the .name
values in variables using as
:
.tables[] |= (
.name as $tname | .fields[] |= (
.name as $fname | .fqn = "\($tname)_\($fname)"
)
)
{
"tables": [
{
"name": "TableA",
"fields": [
{
"name": "FieldA",
"fqn": "TableA_FieldA"
},
{
"name": "FieldB",
"fqn": "TableA_FieldB"
}
]
},
{
"name": "TableB",
"fields": [
{
"name": "FieldA",
"fqn": "TableB_FieldA"
},
{
"name": "FieldB",
"fqn": "TableB_FieldB"
}
]
}
]
}
CodePudding user response:
The following is equivalent to @pmf's solution but is perhaps a little less magical (it uses map
as suggested in the question), and only introduces one variable:
.tables |= map( .name as $name | .fields |= map( .fqn = "\($name)_\(.name)" ))