Home > OS >  Create Bash loop from JSON string using jq
Create Bash loop from JSON string using jq

Time:10-26

I am writing a bash script that reads a JSON string then loop based on the JSON values to execute a CLI command.

#!/usr/bin/env bash

jq --version > /dev/null 2>&1 || { echo >&2 "jq is required but it's not installed. Aborting."; exit 1; }

read -r -d '' USER_ACTIONS << EOM
{
    "user1": [
        "action1"
    ],
    "user2": [
        "action2",
        "action3"
    ]
    
}
EOM

USERS= #TODO
for user in USERS; do
   ACTIONS= #TODO
   for action in ACTIONS; do
       echo "Executing ${command} ${user}-${action}"
   done   
done

If jq is present in the server, how do I populate the USERS and ACTIONS variable?

CodePudding user response:

It seems better to play with vanilla (nodejs):

const myvar={
    "user1": [
        "action1"
    ],
    "user2": [
        "action2",
        "action3"
    ]
};

for (let user in myvar) {
     myvar[user].forEach((action) => {
        console.log("Executing command "   user   "-"   action);
    });
}

Output

Executing command user1-action1
Executing command user2-action2
Executing command user2-action3

Usage

node script.js

Usage with bash

You can remove Executing string, then:

node script.js | bash

CodePudding user response:

Depending on what command you want to execute, if it can be performed from within jq, it's easier to also move the loop inside. There are several ways to accomplish that. Here are some examples, all yielding the same output:

jq -r 'to_entries[] | "Executing command \(.key)-\(.value[])"' <<< "$USER_ACTIONS"
jq -r 'keys[] as $user | "Executing command \($user)-\(.[$user][])"' <<< "$USER_ACTIONS"
jq -r --stream '"Executing command \(.[0][0])-\(.[1]? // empty)"' <<< "$USER_ACTIONS"

Output:

Executing command user1-action1
Executing command user2-action2
Executing command user2-action3
  • Related