awk:将子网掩码转换为前缀
我有一个脚本,将“netstat-rn”中的实际路由表与安全供应商自己的配置中配置的路由表进行比较。 问题是,虽然netstat-rn以“255.255.255.0”的格式提供网络掩码,但用于在供应商中显示路由表的命令以/24的形式提供 我需要找到一种方法,仅使用awk创建一个函数,将子网掩码(例如255.255.255.0)转换为前缀(例如:/24)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
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
}
[改善点]
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)) }';