I've been struggling way too much with something that seems to simple to struggle with.
Routinely throughout the day I use iOs shortcuts to monitor one of my servers, and the shortcuts app is very finicky when it comes to dealing with JSON objects.
I need to return a perfectly formatted (without nesting) array; i.e :
{
{
"term": "alpha"
},
{
"term": "beta"
},
{
"term": "gamma"
},
}
The data is being fetched from an internal API call, of which I need to filter out values from already existing terms. I want to know which objects are returned from the API that are NOT currently a running tmux of same name.
Here's a non-formatted return from API call :
{
"online_terms": [
{
"term": "alpha"
},
{
"term": "beta"
},
{
"term": "gamma"
}
],
"total": 3,
}
Here's the one-liner used currently :
list=$(tmux list-sessions -F \#S); curl https://myapi.call| jq -r '.online_terms[] | .term' | grep -v $list
The $list will contain multiple line LS style names of current running tmux sessions. i.e :
alpha
omega
kappa
That's what I've been using so far, but it's wacky at best. To clarify, declared all my tmux sessions into the $list variable, then do the API call, parse out the nested values i need, inverse grep against the $list ... not ideal !
And it only returns single line names, i.e (filtered out alpha):
beta
gamma
I've not been able to parse it into the type of object explained above despite many attempts to slurp back the raw data into JQ.
I'm welcome to any suggestions as to how to inverse grep the tmux ls values more cleanly, or parse into a proper JSON object, thank you in advance for any help !
To show how jq can be used to solve the problem without any hackery, let's first suppose that the blacklist is somehow available as a text file, say blacklist.txt:
alpha
omega
kappa
Then you could use an invocation of jq along the following lines:
< blacklist.txt jq --argjson curl "$(curl https://myapi.call)" -Rn '
[inputs] as $blacklist
| [ $curl
| .online_terms[]
| select( .term | IN($blacklist[]) | not) ]'
Here, the output of the curl command has been provided to jq using the --argjson
option.
This solution can readily be modified to handle other sources of the black list.
You could also provide the output of the curl command to jq via STDIN, but then you'd first have to convert the textual blacklist into JSON. This could be done by invoking jq once more:
curl https://myapi.call |
jq --argjson blacklist "$(jq -Rn '[inputs]' blacklist.txt)" '
[.online_terms[]
| select( .term | IN($blacklist[]) | not)]'
Not pretty, but it serves to highlight the fact that things would be somewhat simpler if your black list generator could provide the black list as JSON.