【问题标题】:awk: converting subnet mask to prefixawk:将子网掩码转换为前缀
【发布时间】:2021-06-11 08:55:22
【问题描述】:

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

【问题讨论】:

标签: awk


【解决方案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))
}'

你明白了,

/24

【讨论】:

  • 有道理,我想我理解你写的大部分两个函数,除了这部分: if(and(2i, N)) what does and(2i, N) 做吗?
  • 我可以提一下,我使用的 awk 风格不是 gawk,我认为它是 awk 甚至是 hawk。
【解决方案2】:

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

}

【讨论】:

    【解决方案3】:

    [改进点]

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

    【讨论】:

      猜你喜欢
      • 2013-04-10
      • 1970-01-01
      • 2016-02-18
      • 2014-06-14
      • 2021-05-14
      • 2016-03-08
      • 1970-01-01
      • 1970-01-01
      • 2021-06-02
      相关资源
      最近更新 更多