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

awk:将子网掩码转换为前缀,awk,Awk,我有一个脚本,将“netstat-rn”中的实际路由表与安全供应商自己的配置中配置的路由表进行比较。 问题是,虽然netstat-rn以“255.255.255.0”的格式提供网络掩码,但用于在供应商中显示路由表的命令以/24的形式提供 我需要找到一种方法,仅使用awk创建一个函数,将子网掩码(例如255.255.255.0)转换为前缀(例如:/24) function subnetmaskToPrefix(subnetmask) { doing magic } subnetmask="255

我有一个脚本,将“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)

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

掩码
255.255.255.0
是二进制的
11111111.11111111.11111111.00000000
。这是241的

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))
}'

下面的解决方案非常适合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

}
[改善点]

  • 通过减少函数定义的数量,可以节省内存(以及函数调用的操作成本)
  • 掩码二进制文件不能像“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)) }';
    
    awk'函数mask2cidr(mask){
    c=0;拆分(掩码,v,“.”);
    对于(j=1;j=0;i--){
    if(和(2**i,v[j]){c++;}else{return c;}
    }}
    返回c;
    }
    {打印(“/”mask2cidr($1))};
    
    您的问题包括简洁、可测试的示例输入和预期输出,并解释您对所需转换算法的了解。此链接可能有用:有意义,我想我理解您编写的两个函数中的大部分,除了这一部分:if(and(2i,N))what does and(2i,N)是吗?我可以说我用的awk味道不是呆呆的,我想它是awk,甚至是鹰。
        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)) }';