我有一个脚本,我将“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)
答案 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,
&#xA; &#XA;<代码> / 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)
[改进点]
[代码]
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)) }';