如何基于域名后缀列表过滤主机名列表?
问题:过滤掉以指定域名列表中任一域名结尾的主机名
需求说明
我有一组主机名列表,需要过滤掉所有以给定域名列表中任一域名结尾的主机名。
示例
- 主机名列表:
["host1.example.org", "host2.example.org", "example.org", "host.example.com", "host.example.net"]
- 域名列表:
["example.org", "example.net"]
- 过滤结果:
["host.example.com"]
现有单域名过滤方法
针对单个域名的过滤可以用以下jq命令实现:
map(select( . | endswith("example.com") | not ))
但我还没找到针对域名列表的批量过滤方案。
补充背景
这个需求是Shell脚本的一部分,我们有:
- 系统已注册域名列表
${current_domains} - 待添加域名列表
${new_domains} - 正在验证的域名列表
${requested_domains}
目标是筛选出可加入验证流程的域名,要求其所有父域名均未被添加或处于验证流程中。
解决方案
1. 基于jq的批量过滤方法
要实现针对域名列表的批量过滤,可以利用jq的any()函数结合endswith(),遍历域名列表检查匹配项后取反筛选:
假设域名列表是JSON数组格式(比如存放在domains.json),主机名列表在hosts.json中,执行命令:
jq --argfile domains domains.json 'map(select(any($domains[]; . == $item or $item | endswith("." + .)) | not))' hosts.json
逻辑说明
any($domains[]; ...):遍历域名列表里的每个条目,检查当前主机名是否符合匹配条件. == $item or $item | endswith("." + .):覆盖两种匹配场景:- 主机名和域名完全一致(比如
example.org) - 主机名是该域名的子域名(比如
host1.example.org匹配example.org)
- 主机名和域名完全一致(比如
| not:取反逻辑,保留不匹配任何目标域名的主机名
2. 结合Shell变量的完整实现
针对补充背景里的需求,先把三个Shell变量合并成待排除的JSON格式域名列表,再执行过滤:
# 将三个Shell域名列表合并为JSON数组 exclude_domains=$(printf '%s\n' "${current_domains[@]}" "${new_domains[@]}" "${requested_domains[@]}" | jq -R . | jq -s .) # 过滤待验证域名列表(假设待验证列表在requested_hosts.json中) jq --argjson domains "$exclude_domains" 'map(select(any($domains[]; . == $item or $item | endswith("." + .)) | not))' requested_hosts.json
逻辑说明
printf ... | jq -R . | jq -s .:把Shell数组转换成jq能识别的JSON数组格式--argjson:直接传递JSON格式的变量给jq- 该逻辑会自动排除所有父域名在已注册/待添加/验证中列表里的域名,符合需求要求
内容的提问来源于stack exchange,提问作者Clemens Bergmann
相关产品推荐
相关产品推荐

