skip to Main Content

I’ve been trying this for a bit now. I want to loop through all the keys that I pulled out and now want to get the values by looping through those keys in bash.
What I’m trying to do is basically:

I got keys through

keys=$(echo "$tags" | jq -r 'keys[]') where $tags is a json output
The json which is stored in $tags is

{
      "project": "en.wikipedia",
      "article": "Talking_Heads_discography",
      "granularity": "daily",
      "timestamp": "2021092800",
      "access": "all-access",
      "agent": "all-agents",
      "views": 381
    }

Now I wanted to loop through all the keys and get the values for further processing. I wanted to do something like

for key in $keys; do
    value=$(echo $tags | jq -r .[key])
    echo "$key has value $value"
done

Is there an easy way to pass a variable to jq to get the key value
These are the things I tried to pass the variable

for key in $keys; do value=$(echo $tags | jq -r '.[key]'); echo "$key has value $value";done
for key in $keys; do value=$(echo $tags | jq -r '."$key"'); echo "$key has value $value";done
for key in $keys; do value=$(echo $tags | jq -r '."[key]"'); echo "$key has value $value";done
for key in $keys; do value=$(echo $tags | jq -r '.[key]'); echo "$key has value $value";done
for key in $keys;do value=$(echo $tags | jq -r '.[key]'); echo $value;done
for key in $keys;do value=$(echo $tags | jq '.[] | ."$key"' ); echo $value;done

I wanted to do this in bash scripting only

2

Answers


  1. $ echo "$tags" |jq -r 'to_entries[] | "(.key) has value (.value)"'
    project has value en.wikipedia
    article has value Talking_Heads_discography
    granularity has value daily
    timestamp has value 2021092800
    access has value all-access
    agent has value all-agents
    views has value 381
    

    UPDATE

    variant @pmf from comment

    for key in $keys; do value=$(echo $tags | jq --arg k "$key" -r '.[$k]'); echo "$key has value $value";done
    

    but he’s not fast

    it is better to do it through an associative array

    declare -A v
    eval $(echo "$tags" |jq -r 'to_entries[]| "v[(.key)]="(.value)";"')
    for key in $keys; do echo "$key has value ${v[$key]}";done
    
    Login or Signup to reply.
  2. The following illustrates one approach:

    jq -r 'to_entries[][]' | while read -r key ; do
        read -r value
        echo "key=$key and value=$value"
    done
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search