You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash对比两个IP列表变量时如何忽略指定IP段比对差异

Shell实现逗号分隔IP段精准过滤与差异比对

需求说明

  • 变量L1存储从Cloudflare官方下载的最新逗号分隔IP段列表
  • 变量L2存储从现有YAML配置中读取的已配置逗号分隔IP段列表
  • 比对前需从L2中精准移除指定排除段1.2.3.0/32,不得误删其他IP段
  • 排除指定段后若两个列表存在差异,触发邮件告警
  • 已知grep会跳过匹配整行、tr会删除所有匹配字符,无法满足单IP段精准移除要求

现有操作流程

  1. 下载Cloudflare官方IPv4、IPv6地址段
wget https://www.cloudflare.com/ips-v4 && wget https://www.cloudflare.com/ips-v6
  1. 拼接下载的IP段为逗号分隔格式,赋值给L1
L1=$(awk '{printf fmt,$1}' fmt="%s\n" ips-v4 ips-v6 | paste -sd, -)
  1. 从目标YAML配置读取已配置IP段,赋值给L2
L2=$(yq -r .controller.config.proxy-real-ip-cidr yaml.yaml)

变量实际输出示例

  • L1执行输出:
173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22,2400:cb00::/32,2606:4700::/32,2803:f800::/32,2405:b500::/32,2405:8100::/32,2a06:98c0::/29,2c0f:f248::/32
  • L2执行输出(末尾包含需排除的1.2.3.0/32):
173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/12,172.64.0.0/13,131.0.72.0/22,2400:cb00::/32,2606:4700::/32,2803:f800::/32,2405:b500::/32,2405:8100::/32,2a06:98c0::/29,2c0f:f248::/32,1.2.3.0/32

具体实现方案

不要直接在整串上做字符串替换,很容易因为IP段子串匹配误删内容,最稳妥的方式是把逗号分隔的列表拆成单个IP段条目,逐段精确匹配过滤,再排序后做差集,还能避免两个列表IP段顺序不一致导致的误报。

1. 精准过滤L2中指定排除的IP段

通过指定逗号为行分隔符,逐段做精确匹配,只有完全等于排除段的条目才会被跳过,自动适配排除段在列表开头、中间、末尾的所有场景,不会误改其他IP段:

# 定义需要排除的IP段
EXCLUDE_CIDR="1.2.3.0/32"
# 过滤后重新拼接为逗号分隔格式
L2_CLEAN=$(awk -v exclude="$EXCLUDE_CIDR" 'BEGIN{RS=",";ORS=","} $0!=exclude {print}' <<< "$L2" | sed 's/,$//')

2. 标准化两个列表避免顺序干扰

IP段配置不区分先后顺序,因此将两个列表拆分为单个条目后排序,再重新拼接为统一格式,避免顺序不同导致的误报:

# 处理官方最新IP段列表
L1_STD=$(tr ',' '\n' <<< "$L1" | sort | paste -sd, -)
# 处理过滤后的已配置IP段列表
L2_STD=$(tr ',' '\n' <<< "$L2_CLEAN" | sort | paste -sd, -)

3. 差异判断与告警触发

直接比对标准化后的两个字符串即可判断是否存在差异,需要排查具体差异时可以用comm命令输出两边独有的段:

if [ "$L1_STD" != "$L2_STD" ]; then
    echo "=== 检测到Cloudflare IP段配置与官方最新列表存在差异 ==="
    # 输出具体差异明细
    echo "官方列表存在、配置中缺失的段:"
    comm -23 <(tr ',' '\n' <<< "$L1_STD") <(tr ',' '\n' <<< "$L2_STD")
    echo "配置中存在、官方列表没有的段:"
    comm -13 <(tr ',' '\n' <<< "$L1_STD") <(tr ',' '\n' <<< "$L2_STD")
    
    # 此处替换为实际的邮件告警命令
    # mail -s "Cloudflare IP段变更告警" admin@example.com < <(echo "IP段配置存在差异,请及时更新")
fi

效果验证

针对给出的示例变量:

  • 过滤后的L2_CLEAN会精准移除末尾的1.2.3.0/32,不会改动其他段
  • 比对时会准确识别出配置中104.16.0.0/12与官方段104.16.0.0/13、104.24.0.0/14的差异,无漏报误报

内容的提问来源于stack exchange,提问作者DisplayName

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 15:39:15