Issue
I am looking for a way to batch add keys to all JSON file in a directory preferably with command line tools.
Files:
/config$ ls
166bbdd41c0297755ddb645db2b4c865 46a5c83d30483acba49a542a1ade9c33 87b2a640a5398156bf2d924b130ce42c ca5b4cbc16a580cf5236097ec39e90e9
JSON structure is:
{
"enabled": true,
"services": [
"933579ee8caafc4e818ddfe02ab58fdc"
],
"tags": [
"2a521880b86a0f043eb65cff37fac679",
"b4fd044b9a7ab1146bb638ea42219b99"
],
"bouquet": ""
}
The question is, what would be the best way to add new element to array "services" if the file contains "b4fd044b9a7ab1146bb638ea42219b99" value in the "tags" array. If this value does not exists in the "tags" array skip the file, else add "NEWVALUETOADD" to "services".
If "NEWVALUETOADD" already exists we can also skip the file.
Example output:
{
"enabled": true,
"services": [
"NEWVALUETOADD"
"933579ee8caafc4e818ddfe02ab58fdc"
],
"tags": [
"2a521880b86a0f043eb65cff37fac679",
"b4fd044b9a7ab1146bb638ea42219b99"
],
"bouquet": ""
}
Solution
A simple if … then … else … end
might do:
jq --arg q "b4fd044b9a7ab1146bb638ea42219b99" --arg n "NEWVALUETOADD" '
if IN(.tags[]; $q) and (IN(.services[]; $n) | not)
then .services += [$n] else . end
'
{
"enabled": true,
"services": [
"933579ee8caafc4e818ddfe02ab58fdc",
"NEWVALUETOADD"
],
"tags": [
"2a521880b86a0f043eb65cff37fac679",
"b4fd044b9a7ab1146bb638ea42219b99"
],
"bouquet": ""
}
In order to then iterate over each file and modify it you need to use temporary files as jq does not have an in-place editing option (as sed
does with sed -i
).
for file in *
do jq --arg q "b4fd044b9a7ab1146bb638ea42219b99" --arg n "NEWVALUETOADD" '
if IN(.tags[]; $q) and (IN(.services[]; $n) | not)
then .services += [$n] else . end
' "$file" > "$file.new" && mv "$file.new" "$file"
done
Answered By - pmf Answer Checked By - David Goodson (WPSolving Volunteer)