1

I am trying to pass a variable into jq like this '.Linux.date.$var' so far I have tried quoting them by name which is working fine. But I want to use variable to call them.

I have this, which is working fine

exectime=$(date -d now);    
cp $check_exec_history $check_exec_history.tmp
    jq --arg key1 true --arg key2 "$exectime" --arg name "$name" '.Linux.script_executed.first = $key1 | .Linux.date_executed.first = $key2' $check_exec_history.tmp > $check_exec_history; 
    rm $check_exec_history.tmp;

I want to get to this, but not working:

name=first;
exectime=$(date -d now);
cp $check_exec_history $check_exec_history.tmp
jq --arg key1 true --arg key2 "$exectime" --arg name "$name" ".Linux.script_executed.$name = $key1 | .Linux.date_executed.$name = $key2" $check_exec_history.tmp > $check_exec_history; 
rm $check_exec_history.tmp;

I came this far: using this answer https://stackoverflow.com/q/40027395/9496100 But I am not sure where I am doing mistake.

name=first;
exectime=$(date -d now);    
cp $check_exec_history $check_exec_history.tmp
    jq --arg key1 true --arg key2 "$exectime" --arg name "$name" '.Linux.script_executed.name==$name = $key1 | .Linux.date_executed.name==$name = $key2' $check_exec_history.tmp > $check_exec_history; rm $check_exec_history.tmp;
2

You can use square bracket indexing on all objects in jq, so [$name] works for what you're trying:

jq --arg key1 true --arg name "$name" '.Linux.script_executed[$name] = $key1 ...' 

This use of square brackets is not very well documented in the manual, which makes it look like you can only use .[xyz], but ["x"] works anywhere that .x would have as long as it's not right at the start of an expression (that is, .a.x and .a["x"] are the same, but ["x"] is an array construction).

Note the use of single quotes above - that is so Bash won't try to interpret $name and $key1 as shell variables. You should keep the double quotes for --arg name "$name", because that really is a shell variable, and it should be quoted to make it safe to use.

-1

Michael Homer has the correct response. I'll post what I was aiming for in relation to op's question.

I am trying to modify a permissions graph obtained through a REST API curl call using jq to output a json file which I will PUT to the server with updates. The following is the output of the curl API query:

{
  "revision": 2,
  "groups": {
    "1": {
      "1": {
        "native": "none",
        "schemas": "none"
      },
      "2": {
        "native": "write",
        "schemas": "all"
      }
    },
    "2": {
      "1": {
        "native": "write",
        "schemas": "all"
      },
      "2": {
        "native": "write",
        "schemas": "all"
      }
    }
  }
}

As you can see it is nested. I am trying to modify this using bash variables every time a new permission set is created and when databases are created. For exmaple I'm trying to modify groups."1"."2"."native" and "schemas" also "groups."2"."2".native and "schemas" values. It's rough, but the keys are as follows groups.groupPermissionID.DatabaseID.*

In order to modify this nested graph on the fly via a bash shell script, I used Michael Homer's solution of applying [$name]. In my case I had to do this twice in a row. i.e., [$gID][$dID]. In the following setup the variables are constant but in my model they are command arguments passed to the bash shell script.

dbID="2"
pgroupID="2"

curl -X GET -H "Content-Type: application/json" -H "X-Metabase-Session: XXXXX-XXXXX-XXXXX-XXXXXXXXX" "http://localhost:9000/api/permissions/graph" | jq --arg dID "$dbID"   --arg gID "$pgroupID" -r '.groups."1"[$dID]."native" = "none" | .groups."1" [$dID]."schemas" = "none" | .groups[$gID][$dID]."native" ="none" .groups[$gID][$dID]."schemas" ="none"' > permissiongraph.json

Which produced the following updated JSON graph for me to PUT to my server:

{
  "revision": 2,
  "groups": {
    "1": {
      "1": {
        "native": "none",
        "schemas": "none"
      },
      "2": {
        "native": "none",
        "schemas": "none"
      }
    },
    "2": {
      "1": {
        "native": "write",
        "schemas": "all"
      },
      "2": {
        "native": "none",
        "schemas": "none"
      }
    }
  }
}

Michael is correct when he said this is sparsely documented. I couldn't find it anywhere in the manuals. I hope this helps someone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.