to edit a json file inplace with JQ like -i
in sed I have found many solutions like
jq ... input.json > tmp.json && mv tmp.json input.json
This works, but I need to filter on my file, add some data, and place it back in the original. (ie. Update a specific object in a file)
My file contains over 1000 objects with different Element
. I will always be using a filter on Element
, I shortened for question. I have a sample file original.json
...
{
"Element": "acton",
"objectName": "contacts",
"Path": "/contacts",
"Scenario": "",
"serviceLevel": "",
"IBM": "",
"Gap": "",
"clientPhase": "",
"parentPhase": "",
"existsToday": ""
}
{
"Element": "acton",
"objectName": "optouts",
"Path": "/optouts",
"Scenario": "",
"serviceLevel": "",
"IBM": "",
"Dependency": "",
"Gap": "",
"clientPhase": "",
"parentPhase": "",
"existsToday": ""
}
{
"Element": "acton",
"objectName": "subscriptionTypes",
"Path": "/subscription-types",
"Scenario": "",
"serviceLevel": "",
"IBM": "",
"Dependency": "",
"Gap": "",
"clientPhase": "",
"parentPhase": "",
"existsToday": ""
}
I want to filter by objectName
for contacts
add some data to empty IBM field and save to the file
Applying the same logic to inplace edit the IBM field to "Y"
on object containing "objectName": "contacts"
jq 'select(.objectName == "contacts") | .IBM = "Y"' original.json > tmpjson.json && mv tmpjson.json original.json
Now my file original.json
shows
{
"Element": "acton",
"objectName": "contacts",
"Path": "/contacts",
"Scenario": "",
"serviceLevel": "",
"IBM": "Y",
"Dependency": "",
"Gap": "",
"clientPhase": "",
"parentPhase": "",
"existsToday": ""
}
Expected Result
{
"Element": "acton",
"objectName": "contacts",
"Path": "/contacts",
"Scenario": "",
"serviceLevel": "",
"IBM": "Y",
"Gap": "",
"clientPhase": "",
"parentPhase": "",
"existsToday": ""
}
{
"Element": "acton",
"objectName": "optouts",
"Path": "/optouts",
"Scenario": "",
"serviceLevel": "",
"IBM": "",
"Dependency": "",
"Gap": "",
"clientPhase": "",
"parentPhase": "",
"existsToday": ""
}
{
"Element": "acton",
"objectName": "subscriptionTypes",
"Path": "/subscription-types",
"Scenario": "",
"serviceLevel": "",
"IBM": "",
"Dependency": "",
"Gap": "",
"clientPhase": "",
"parentPhase": "",
"existsToday": ""
}
It seems after using select I can no longer use the provided solution https://github.com/stedolan/jq/wiki/FAQ#general-questions
Your jq filter is not the one you need because select
selects. That is, it filters out the objects that don't match the selection criterion.
This jq filter should do what you want:
if (.objectName == "contacts") then .IBM = "Y" else . end
As for overwriting the file, many people who have access to sponge
(part of the moreutils collection of CLI utilities) use it, e.g.
jq 'if (.objectName == "contacts") then .IBM = "Y" else . end' input.json |
sponge input.json