ipvsadm 输出处理

ipvsadm 输出处理

我需要处理类似于此的 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

相关内容