Wednesday, August 31, 2022

[SOLVED] jq: how to check two conditions in the any filter?

Issue

I have this line jq 'map(select( any(.topics[]; . == "stackoverflow" )))'

Now I want to modify it (I didn't write the original) to add another condition to the any function.

Something like this jq 'map(select( any(.topics[]; . == "stackoverflow" and .archived == "false" )))'

But it gives me “Cannot index string with string “archived”".

The archive field is on the same level as the topics array (it's repo information from the github API).

It is part of a longer command, FYI:

repositoryNames=$(curl \
      -H "Authorization: token $GITHUB_TOKEN" \
      -H "Accept: application/vnd.github.v3+json" \
      "https://api.github.com/orgs/organization/repos?per_page=100&page=$i" | \
    jq 'map(select(any(.topics[]; . == "stackoverflow")))' | \
    jq -r '.[].name')

Solution

The generator provided to any already descends to .topics[] from where you cannot back-reference two levels higher. Use the select statement to filter beforehand (also note that booleans are not strings):

jq 'map(select(.archived == false and any(.topics[]; . == "stackoverflow")))'

You should also be able to combine both calls to jq into one:

jq -r '.[] | select(.archived == false and any(.topics[]; . == "stackoverflow")).name'


Answered By - pmf
Answer Checked By - Pedro (WPSolving Volunteer)