vespino
vespino

Reputation: 1940

loop json file/array linux bash

I have a json file that looks like this:

{"data":{"players":[{"id":"aaaa","is_multiple":false,"name":"TV Woonkamer","password_protected":false,"support_seek":false,"support_set_volume":false,"type":"upnp"},{"id":"bbbb","is_multiple":false,"name":"squeezelite","password_protected":false,"support_seek":true,"support_set_volume":true,"type":"upnp"},{"id":"cccc","is_multiple":false,"name":"Woonkamer","password_protected":false,"support_seek":true,"support_set_volume":true,"type":"airplay"},{"id":"__dddd__","is_multiple":true,"name":"Multiple AirPlay Devices","password_protected":false,"support_seek":true,"support_set_volume":true,"type":"airplay"}]},"success":true}

Parsed by PHP:

stdClass Object
(
[data] => stdClass Object
    (
        [players] => Array
            (
                [0] => stdClass Object
                    (
                        [id] => uuid:aaaa
                        [is_multiple] => 
                        [name] => TV Woonkamer
                        [password_protected] => 
                        [support_seek] => 
                        [support_set_volume] => 
                        [type] => upnp
                    )

                [1] => stdClass Object
                    (
                        [id] => uuid:bbbb
                        [is_multiple] => 
                        [name] => squeezelite
                        [password_protected] => 
                        [support_seek] => 1
                        [support_set_volume] => 1
                        [type] => upnp
                    )

                [2] => stdClass Object
                    (
                        [id] => cccc
                        [is_multiple] => 
                        [name] => Woonkamer
                        [password_protected] => 
                        [support_seek] => 1
                        [support_set_volume] => 1
                        [type] => airplay
                    )

                [3] => stdClass Object
                    (
                        [id] => __dddd__
                        [is_multiple] => 1
                        [name] => Multiple AirPlay Devices
                        [password_protected] => 
                        [support_seek] => 1
                        [support_set_volume] => 1
                        [type] => airplay
                    )

            )

    )

[success] => 1
)

I would like to loop through it from a linux command line and found all IDs of players where is_multiple is empty and type is airplay. The following shows a list of all players with type is airplay, but how do I start a loop?

jq '.data .players[]' scan.json | jq 'select(.type=="airplay")' | jq -r '.id'

Upvotes: 0

Views: 253

Answers (2)

vespino
vespino

Reputation: 1940

I solved it as followed:

jq -r '.data.players[]|select(.type == "airplay" and .is_multiple == false)|.id' players.json | while read i; do
    # i is the id of the player
    echo $i
done

Thanks @liborm for helping me on my way!

Upvotes: 0

liborm
liborm

Reputation: 2724

I believe the code you're after is something like

<scan.json jq -r '.data.players[]|select(.type == "airplay" and .is_multiple == false)|.id' |
   xargs -I{} wget -q "https://my.web/?id={}"

If the operation with each id is more complex, you can wrap it either in a .sh script, or in a bash function (like process_one_id(){ commands.. ;}.

NB: to use a bash function with xargs you have to do export -f process_one_id and then call it through bash like xargs -I {} bash -c process_one_id {}. Or use GNU parallel which makes it transparent to call exported shell functions.

Upvotes: 1

Related Questions