4

I would like a string of all my HomePod ids. I can loop a file called players.json:

homepods=""
jq -r '.data.players[]|select(.type == "airplay" and .is_multiple == false)|.id' players.json | while read homepod; do
    homepods+="$homepod,"
done

echo $homepods

I would expect the outcome to be id,id,id, but $homepods is empty. When I echo $homepods inside the loop the output is as expected.

vespino
  • 1,714
  • 3
  • 15
  • 28

2 Answers2

3

You can use the following script:-

homepods=""
for homepod in `jq -r '.data.players[]|select(.type == "airplay" and .is_multiple == false)|.id' players.json` ; do
    homepods+="$homepod,";
done

echo $homepods
nandal
  • 2,544
  • 1
  • 18
  • 23
2

The pipe starts a new process in a new environment which has a copy of the parent process' environment, hence it cannot change the parent variables.

So, you need an alternative approach:

homepods=$( 
    printf "%s," $(
    jq -r '.data.players[]|select(.type == "airplay" and .is_multiple == false)|.id' players.json
))

In this case the parent is capturing the output of the child instead.

or alternatively:

homepods=$(
  jq -r '.data.players[]|select(.type == "airplay" and .is_multiple == false)|.id' players.json | while read homepod; do
    echo "$homepod,"
  done)

Answering your additional request: you could also echo the counter and then split it up from the captured output. However, there is an easier alternative:

homepods_array=(${homepods//,/ })
homepods_count=${#homepods_array[@]}

That is converting the string to a bash array and then recovering the length of the array. That is also using bash string manipulation to replace the commas for spaces.

BTW, using string manipulation you can get your ids in many formats with no loops at all:

homepods_lines=$(jq -r '.data.players[]|select(.type == "airplay" and .is_multiple == false)|.id' players.json)
homepods_spaces=${homepods_lines//$'\n'/ }
homepods_commas=${homepods_lines//$'\n'/,}
homepods_array=(homepods_lines)
homepods_count=${#homepods_array[@]}
olivecoder
  • 2,858
  • 23
  • 22