awk:将子网掩码转换为前缀

时间:2016-11-25 15:03:17

标签: awk awk-formatting

我有一个脚本,我将“netstat -rn”中的实际路由表与安全厂商自己配置中配置的路由表进行比较。 问题是,当netstat -rn给出网络掩码的格式为“255.255.255.0”时,在供应商中显示路由表的命令以/ 24

的形式给出它

我需要找到一种创建函数的方法,仅使用awk,将子网掩码(例如255.255.255.0)转换为前缀,例如:/ 24

function subnetmaskToPrefix(subnetmask) {
doing magic
}

subnetmask="255.255.255.0"
prefix=subnetmaskToPrefix(subnetmask)

3 个答案:

答案 0 :(得分:1)

如果前缀编号来自转换为二进制时子网掩码中的1的编号。示例:





掩码 255.255.255.0 是二进制的 11111111.11111111.11111111.00000000 。这是24 1。




  echo“255.255.255.0”| awk'
 function count1s(N){
 c = 0
 for(i = 0; i< 8; ++ i)if(and(2 ** i,N))++ c
 return c
}
 function subnetmaskToPrefix(subnetmask){
 split(subnetmask,v,“。”)
 return count1s(v [1])+ count1s(v [2])+ count1s(v [3])+ count1s(v [4])
}
 {
 print(“/”subnetmaskToPrefix($ 1))
}'
  




you get,


 

 <代码> / 24&#XA;  
&#XA;

答案 1 :(得分:1)

以下解决方案非常适合gawk。但是如果你不使用gawk,那么你可以使用这个函数来计算。

function count1s(N) {
    r=""                    # initialize result to empty (not 0)
    while(N!=0){            # as long as number still has a value
        r=((N%2)?"1":"0") r   # prepend the modulos2 to the result
        N=int(N/2)            # shift right (integer division by 2)
    }

    # count number of 1s
    r=gsub(/1/,"",r)
    # Return result
    return r

}

答案 2 :(得分:0)

[改进点]

  1. 您可以通过减少函数定义的数量来节省内存(以及函数调用的运营成本)。
  2. 掩码二进制不能像“11101”一样。因此,可以中断子循环(= 原始代码的预函数)。

[代码]

    awk 'function mask2cidr(mask){
      c=0; split(mask,v,".");
      for(j=1; j<5; j++){for(i=7; i>=0; i--){
        if(and(2**i,v[j])){c++;}else{return c;}
      }}
      return c;
    }
    { print("/" mask2cidr($1)) }';