咨询如何将压缩格式IPv6转换为完整展开格式
咨询如何将压缩格式IPv6转换为完整展开格式
嘿,我之前刚好遇到过这个问题,给你几个实用的方法,能把压缩格式的IPv6转成带全零填充的完整格式,这样后续正则匹配就没问题了:
方法1:用sipcalc工具快速处理
sipcalc是专门用来处理IP地址计算和格式化的工具,大部分Linux发行版都能直接安装:
- Debian/Ubuntu系列:
sudo apt install sipcalc - RHEL/CentOS系列:
sudo yum install sipcalc
安装完成后,执行这条命令就能提取并展开所有IPv6地址:
ip address show | grep -oP 'inet6 \K[^/]+' | while read ip; do # 提取完整未压缩的IPv6地址 full_addr=$(sipcalc $ip | grep -oP 'Full Uncompressed.*\K[^ ]+') # 提取前缀长度 prefix=$(ip address show | grep "$ip/" | grep -oP '/\K[0-9]+') echo "${full_addr}/${prefix}" done
这个命令先提取出所有IPv6的地址主体,再通过sipcalc生成完整格式,最后拼接上前缀长度输出。
方法2:用Python脚本处理(无需额外安装工具)
如果你的服务器已经预装了Python(大部分Linux服务器默认都有),这个方法最可靠,不会因为工具版本差异出问题:
先创建一个名为expand_ipv6.py的脚本:
import socket import sys for line in sys.stdin: line = line.strip() if not line: continue # 分离地址和前缀长度 if '/' in line: addr_part, prefix = line.split('/', 1) else: addr_part, prefix = line, '' try: # 利用socket库的内置函数展开IPv6 packed_addr = socket.inet_pton(socket.AF_INET6, addr_part) expanded_addr = socket.inet_ntop(socket.AF_INET6, packed_addr) if prefix: print(f"{expanded_addr}/{prefix}") else: print(expanded_addr) except ValueError: # 跳过无效的IPv6地址 continue
然后用这条命令调用脚本:
ip address show | grep -oP 'inet6 \K[^ ]+' | python expand_ipv6.py
Python的socket库原生支持IPv6的压缩和解压缩,逻辑非常稳定,能准确输出标准的8段完整IPv6地址。
方法3:用Awk脚本纯文本处理(无外部依赖)
如果你的环境不能安装工具也不想用Python,可以用Awk写个纯文本解析脚本,完全靠字符串处理补全压缩的IPv6:
创建expand_ipv6.awk脚本:
# 定义展开单个IPv6地址的函数 function expand_ipv6(ip) { # 处理双冒号代表的压缩段 split(ip, parts, /::/) if (length(parts) == 2) { left_seg = parts[1] right_seg = parts[2] split(left_seg, left_parts, /:/) split(right_seg, right_parts, /:/) # 计算需要补充的0段数量(IPv6共8个4位段) missing = 8 - (length(left_parts) + length(right_parts)) expanded = left_seg for (i=1; i<=missing; i++) { expanded = expanded ":0000" } expanded = expanded ":" right_seg } else { expanded = ip } # 把每个段补全到4位 split(expanded, segs, /:/) result = "" for (i in segs) { seg = segs[i] if (seg == "") continue while (length(seg) < 4) { seg = "0" seg } result = result seg ":" } # 去掉末尾多余的冒号 return substr(result, 1, length(result)-1) } # 处理ip address show的输出行 { if ($1 == "inet6") { split($2, ip_info, /\//) expanded_ip = expand_ipv6(ip_info[1]) print expanded_ip "/" ip_info[2] } }
运行命令:
ip address show | awk -f expand_ipv6.awk
这个脚本完全通过字符串解析来补全压缩的IPv6段,适合没有任何额外依赖的极端环境。
顺便提一句:你示例里写的3600:3c00:e000:092b:0000:0005/64其实不是标准的完整IPv6格式(完整格式应该是8个4位段),不过上面的方法都会输出标准的8段完整地址,比如把3600:3c00:e000:92b::5/64转换成3600:3c00:e000:092b:0000:0000:0000:0005/64,这完全不影响你的正则匹配需求。
备注:内容来源于stack exchange,提问作者Samul
相关产品推荐
相关产品推荐

