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

使用SED匹配IPv4后删除尾部冒号及端口 保留完整IPv6地址

问题背景

现有脚本需要匹配openvpn状态日志中指定私网IP对应的行,打印第三列内容。第三列存在两种取值:

  • IPv4地址:末尾固定附带:PORT格式的数字端口后缀
  • IPv6地址:无额外后缀,地址本身包含多个冒号分隔符

现有处理方案存在两类典型错误:

  • 直接执行sed 's/:.*//g'删除冒号后所有内容,会破坏IPv6地址的原有格式
  • 为awk指定多分隔符[,:],虽能正确提取IPv4地址,但会按冒号截断IPv6地址,仅输出第一个地址段

核心需求:仅剥离IPv4地址末尾的:PORT后缀,完整保留IPv6地址


测试样例

测试用openvpn-status.log文件内容如下:

$ cat openvpn-status.log
10.13.0.27,ijegunbead-4,74.201.72.222:49911,2022-06-26 02:55:26
10.13.0.23,biddy-h-1,2803:4600:1111:17ec:a821:1a8:53ca:760d,2022-06-26 02:55:28

原有提取命令:

dst1=$(egrep -w ^$dst /etc/openvpn/openvpn-status.log | awk -F'[,:]' '{print $3}')

命令错误输出:

74.201.72.222
2803

期望正确输出:

74.201.72.222
2803:4600:1111:17ec:a821:1a8:53ca:760d

之前尝试的失败命令存在两个问题:一是管道位置错误,sed未接收到子shell输出的内容;二是sed正则替换逻辑写反,会误删IPv4地址本身。

# 错误示例,请勿使用
dst1=$(egrep -w ^$dst /etc/openvpn/openvpn-status.log | awk -F',' '{print $3}') | sed 's/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:*//g'

正确实现方案

直接用awk单命令完成匹配、判断、替换全流程,避免多管道开销,逻辑更精准:

dst1=$(awk -F',' -v match_ip="$dst" '
$1 == match_ip {
    # 仅当第三列是带端口的IPv4地址时,删除末尾的端口后缀
    if ($3 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]+$/) {
        sub(/:[0-9]+$/, "", $3)
    }
    print $3
    exit
}' /etc/openvpn/openvpn-status.log)

逻辑说明

  • 仅用逗号作为字段分隔符,从根源避免IPv6地址被冒号截断
  • 通过-v参数传入shell变量,避免引号转义问题,匹配第一列完全等于目标IP的行,比grep模糊匹配更准确,不会出现前缀误判
  • 对第三列做格式校验:只有符合「IPv4+冒号+数字端口」格式的内容,才会删除末尾的:端口后缀;IPv6地址会原样保留
  • 匹配到目标行后直接exit退出,适合大日志文件场景,减少无效遍历

执行后即可得到预期输出,完全满足需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:54:08