Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using jq to assign multiple output variables

Tags:

I am trying to use jq to parse information from the TVDB api. I need to pull a couple of fields and assign the values to variables that I can continue to use in my bash script. I know I can easily assign the output to one variable through bash with variable="$(command)" but I need the output to produce multiple variables and I don't want to make to use multiple commands.

I read this documentation:

https://stedolan.github.io/jq/manual/v1.5/#Advancedfeatures

but I don't know if this relevant to what I am trying to do.

jq '.data' produces the following output:

[   {     "absoluteNumber": 51,     "airedEpisodeNumber": 6,     "airedSeason": 4,     "airedSeasonID": 680431,     "dvdEpisodeNumber": 6,     "dvdSeason": 4,     "episodeName": "We Will Rise",     "firstAired": "2017-03-15",     "id": 5939660,     "language": {       "episodeName": "en",       "overview": "en"     },     "lastUpdated": 1490769062,     "overview": "Clarke and Roan must work together in hostile territory in order to deliver an invaluable asset to Abby and her team."   } ] 

I tried jq '.data | {episodeName:$name}' and jq '.data | .episodeName as $name' just to try and get one working. I don't understand the documentation or even if it's what I'm looking for. Is there a way to do what I am trying to do?

like image 795
user2328273 Avatar asked Apr 08 '17 07:04

user2328273


1 Answers

You can use separate variables with read :

read var1 var2 var3 < <(echo $(curl -s 'https://api.github.com/repos/torvalds/linux' |       jq -r '.id, .name, .full_name'))  echo "id        : $var1" echo "name      : $var2" echo "full_name : $var3" 

Using array :

read -a arr < <(echo $(curl -s 'https://api.github.com/repos/torvalds/linux' |       jq -r '.id, .name, .full_name'))  echo "id        : ${arr[0]}" echo "name      : ${arr[1]}" echo "full_name : ${arr[2]}" 

Also you can split jq output with some character :

IFS='|' read var1 var2 var3 var4 < <(curl '......' | jq -r '.data |      map([.absoluteNumber, .airedEpisodeNumber, .episodeName, .overview] |      join("|")) | join("\n")') 

Or use an array like :

set -f; IFS='|' data=($(curl '......' | jq -r '.data |      map([.absoluteNumber, .airedEpisodeNumber, .episodeName, .overview] |      join("|")) | join("\n")')); set +f 

absoluteNumber, airedEpisodeNumber, episodeName & overview are respectively ${data[0]}, ${data[1]}, ${data[2]}, ${data[3]}. set -f and set +f are used to respectively disable & enable globbing.

For the jq part, all your required fields are mapped and delimited with a '|' character with join("|")

If your are using jq < 1.5, you'll have to convert Number to String with tostring for each Number fields eg:

IFS='|' read var1 var2 var3 var4 < <(curl '......' | jq -r '.data |      map([.absoluteNumber|tostring, .airedEpisodeNumber|tostring, .episodeName, .overview] |      join("|")) | join("\n")') 
like image 64
Bertrand Martel Avatar answered Oct 24 '22 20:10

Bertrand Martel