我需要处理类似于此的 ipvsadm 输出:
IP Virtual Server version 0.2.12 (size=16384)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP lvs2.mack.net:0 rr persistent 360
-> RS2.mack.net:0 Route 1 0 0
-> RS1.mack.net:0 Route 1 0 0
-> RS3.mack.net:0 Route 1 0 0
TCP lvs2.mack.net:https rr
-> RS2.mack.net:https Route 1 0 0
TCP lvs2.mack.net:telnet rr
-> RS2.mack.net:telnet Route 1 0 0
-> RS1.mack.net:telnet Route 1 0 0
TCP lvs2.mack.net:ssh rr
TCP lvs2.mack.net:hvr rr
在输出中,我预计只有这些 VIP 目前“活动”的真实节点数少于 2 个。因此,处理上面的示例数据,预期输出是:
TCP lvs2.mack.net:https rr
-> RS2.mack.net:https Route 1 0 0
TCP lvs2.mack.net:ssh rr
TCP lvs2.mack.net:hvr rr
因为正如我们所看到的,一个 VIP 只有 1 个真实节点处于活动状态,而另外两个则不可用。
答案1
Awk
解决方案:
awk 'NR<4{ next }
/TCP/{ if (host && c<2) printf "%s%s\n",host,(c==1? ORS node:""); host=$0; c=0 }
host && $1=="->"{ node=$0; c++ }
END{ if (host && c<2) print host }' file
NR<4{ next }
- 跳过前 3 行(NR
表示已读取的总行数)/TCP/
- 遇到时主持人行开头为TCP
:host=$0
- 将整行捕获到变量中host
c=0
- 计算当前的节点数主持人if (host && c<2) printf "%s%s\n",host,(c==1? ORS node:"")
- 如果有一个先前处理过的主机并且其节点数为c<2
- 打印主机行及其节点(如果存在)
host && $1=="->"{ node=$0; c++ }
- 对于当前处理的主持人- 捕获其节点将行写入变量node
并增加节点数c++
END{ if (host && c<2) print host }
- 检查已处理但未打印的剩余主机
输出:
TCP lvs2.mack.net:https rr
-> RS2.mack.net:https Route 1 0 0
TCP lvs2.mack.net:ssh rr
TCP lvs2.mack.net:hvr rr