Home > Enterprise >  Batch add keys into JSON files in a directory based on condition
Batch add keys into JSON files in a directory based on condition

Time:01-19

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": ""
}

CodePudding user response:

This way:

jq --arg nv "NEWVALUETOADD" 'select(.tags[] | select(. == "b4fd044b9a7ab1146bb638ea42219b99") ).services  = [$nv]'

The jq script:

select(
  .tags[] | select(
    . == "b4fd044b9a7ab1146bb638ea42219b99"
  )
).services  = [$nv]

jqplay.org with this above

CodePudding user response:

One option would be using index in order to find exact match with the desired value and then add the new element such as

jq '(select(.tags | index("b4fd044b9a7ab1146bb638ea42219b99")).services ) =["New Value"]' yourfile  

Demo

CodePudding user response:

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": ""
}

Demo

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
  •  Tags:  
  • Related