jq

How to filter list based on prefix list?


I have a list of hostnames and I want to filter out all hostnames that end in any of a given list of domains.

For example for the hostnames

["host1.exmaple.org", "host2.example.org", "example.org", "host.example.com", "host.example.net"]

and the domain List

["example.org", "example.net"]

the result should be

["host.example.com"]

Filtering against one value works like this

map(select( . | endswith("example.com") | not ))

but I have not found a solution for a list of domains.

For those who are interested here is a little bit more context:

All this is part of a shell script.

We have a list of domains that are currently registed with the system (${current_domains}), a list of domains that we want to add (${new_domains}) and a list of domains that are currently in a validation process (${requested_domains}).

The goal is to get a list of domains that should be inserted added to the validation process but only of none of the "parent" domains are already added or in the process of being added.


Solution

  • select those where all variants are not approved by endswith. Assuming the hostnames array is the context, and the domains are bound to a variable:

    ["example.org","example.net"] as $domains
    | map(select(all(endswith($domains[]); not)))
    
    [
      "host.example.com"
    ]
    

    Demo

    (Note that host1.exmple.org is not shown because backed by your expected results, I assumed this is a typo in the hostnames, and changed it manually to host1.example.org, so it can be caught by endswith.)