'JQ - Get specific values under a key based on variable filter

So for class I have to make an shell script (BASH) that uses JQ to display a superheroes secret identity and powers. It has been a pretty fun course.

The script prints the hero names to the user, who then specifies which heroes details they want to see.

Here is a small part of the json file that I have been given.

{
  "squadName": "Super hero squad",
  "homeTown": "Metropolia",
  "formed": 2013,
  "secretBase": "Super HQ",
  "active": true,
  "members": [
    {
      "name": "Atom Man",
      "age": 25,
      "secretIdentity": "Dan Smith",
      "powers": [
        "Radiation resistance",
        "Radiation blast"
      ]
    }
  ]
}

So if the user enters "Atom Man", the script should print his secret identity ("secretIdentity": "Dan Smith") and his powers.

("powers": [
        "Radiation resistance",
        "Radiation blast"
      ])

And here is the partially done script.

#!/bin/bash
while [ true ]
do
cat superhero.json | jq -r '.mem [] | .name' #display the hero names for user.
  read -p "Which heroes details do you want to see? Enter 'exit' to quit. :" HERONAME1
  if [ "$HERONAME1" = "exit" ]
  then
    echo "Quitting..."
    exit
  else
    cat superhero.json | jq -r '.member [] | .name [] '
    #or jq '.members[].name' superhero.json'
  fi
done

Now I am stuck at this part of my script.

else
    cat superhero.json | jq -r '.member [] | .name [] '

I don't quite understand how I can filter a certain hero from the json file using the HERONAME1 variable and how to include their powers in the output as well.

Any and all pointers are highly appreciated!



Solution 1:[1]

Here's my take on this.

Say we have superhero.json like this:

{
  "squadName": "Super hero squad",
  "homeTown": "Metropolia",
  "formed": 2013,
  "secretBase": "Super HQ",
  "active": true,
  "members": [
    {
      "name": "Atom Man",
      "age": 25,
      "secretIdentity": "Dan Smith",
      "powers": [
        "Radiation resistance",
        "Radiation blast"
      ]
    },
    {
      "name": "Super Man",
      "age": 26,
      "secretIdentity": "Clark",
      "powers": [
        "Flying power",
        "Super human strength"
      ]
    },
    {
      "name": "Bat Man",
      "age": 24,
      "secretIdentity": "Bruce",
      "powers": [
        "Pakour",
        "Night vision"
      ]
    }
  ]
}

And here's my run.sh script:

#!/bin/bash
while true
do
jq -r '.members[] | .name' superhero.json #display the hero names for user.
  read -p "Which heroes details do you want to see? Enter 'exit' to quit: " HERONAME1
  if [ "$HERONAME1" = "exit" ]
  then
    echo "Quitting..."
    exit
  else
    HERONAME1=$HERONAME1 jq -r '.members[] | select(.name==env.HERONAME1) | {secretIdentity}, {powers}' superhero.json
  fi
done

Here's output when I run this script:

$ ./run.sh 
Atom Man
Super Man
Bat Man
Which heroes details do you want to see? Enter 'exit' to quit: Bat Man
{
  "secretIdentity": "Bruce"
}
{
  "powers": [
    "Pakour",
    "Night vision"
  ]
}
Atom Man
Super Man
Bat Man
Which heroes details do you want to see? Enter 'exit' to quit: Atom Man
{
  "secretIdentity": "Dan Smith"
}
{
  "powers": [
    "Radiation resistance",
    "Radiation blast"
  ]
}
Atom Man
Super Man
Bat Man
Which heroes details do you want to see? Enter 'exit' to quit: Super Man 
{
  "secretIdentity": "Clark"
}
{
  "powers": [
    "Flying power",
    "Super human strength"
  ]
}
Atom Man
Super Man
Bat Man
Which heroes details do you want to see? Enter 'exit' to quit: exit
Quitting...

Try the script. ;)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Logan Lee