免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8177 | 回复: 13
打印 上一主题 下一主题

如何用脚本自动合并网段的掩码位? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-14 09:36 |只看该作者 |倒序浏览

  1. 202.88.64.0/18
  2. 202.88.120.0/22
  3. 202.88.128.0/22
  4. 202.88.200.0/22
  5. 202.88.204.0/22
  6. 210.89.0.0/19
  7. 210.89.192.0/19
  8. 210.176.0.0/17
  9. 210.176.32.0/20
  10. 210.176.48.0/20
  11. 210.176.64.0/18
  12. 210.176.128.0/19
  13. 210.176.160.0/19
复制代码


用脚本自动合并后,结果为

  1. 202.88.64.0/18
  2. 202.88.128.0/22
  3. 202.88.200.0/21
  4. 210.89.0.0/19
  5. 210.89.192.0/19
  6. 210.176.0.0/17
  7. 210.176.128.0/18
复制代码


就是得到的地址段不要重复,朋友说perl有个CIDR的现成模块可以,不过就是要拆开,合并再反复

不知道bash配合awk sed之类的工具是否能实现,各位高手帮忙看看?

[ 本帖最后由 killua 于 2008-7-14 15:55 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-07-14 14:42 |只看该作者
我自己写的一个脚本

CIDR.sh


  1. #!/bin/bash
  2. function IP2long(){
  3.   local IFS='.'
  4.   read IP1 IP2 IP3 IP4 <<<"$1"
  5.   echo $((IP1*256*256*256+IP2*256*256+IP3*256+IP4))
  6. }

  7. function long2IP(){
  8.   local IP=$1
  9.   local NET=
  10.   NET=".$(( IP - (IP >> 8 << 8 ) ))${NET}"
  11.   (( IP >>= 8 ))
  12.   NET=".$(( IP - (IP >> 8 << 8 ) ))${NET}"
  13.   (( IP >>= 8 ))
  14.   NET=".$(( IP - (IP >> 8 << 8 ) ))${NET}"
  15.   (( IP >>= 8 ))
  16.   NET="${IP}${NET}"
  17.   echo $NET
  18. }

  19. function cidr(){
  20.   local IFS='~'
  21.   local MASK=0
  22.   local HOSTS=0
  23.   read IPstart IPend <<<"$1"
  24.   start=$(IP2long $IPstart)
  25.   end=$(IP2long $IPend)
  26.   while [ $MASK -le 32 ]
  27.   do
  28.     if [ $(( start + ( 1 << MASK) -1 )) -eq $end ];then
  29.       echo "$IPstart/$(( 32-MASK))"
  30.       break
  31.     elif [ $(( start + (1 << MASK) -1 )) -gt $end ];then
  32.       ((MASK--))
  33.       echo "$IPstart/$(( 32-MASK))"
  34.       (( start += (1<<MASK) ))
  35.       IPstart=$(long2IP $start)
  36.       MASK=0
  37.     elif [ $(( (start>>MASK) % 2 )) -eq 1 ];then
  38.       echo "$IPstart/$(( 32-MASK))"
  39.       (( start += (1<<MASK) ))
  40.       IPstart=$(long2IP $start)
  41.       MASK=0
  42.     else
  43.       (( MASK ++ ))
  44.     fi
  45.   done
  46. }

  47. function formatIP(){
  48.   case $1 in
  49.     *~*)
  50.       echo $1
  51.       ;;
  52.     */*)
  53.       start=${1%/*}
  54.       mask=${1#*/}
  55.       if [ ${#mask} -gt 2 ];then
  56.         end=$(( $(IP2long $start) + (1<<32) - $(IP2long $mask) -1 ))
  57.       else
  58.         end=$(( $(IP2long $start) + (1 << (32-mask)) -1 ))
  59.       fi
  60.       echo "$start~$(long2IP $end)"
  61.       ;;
  62.     *)
  63.       echo
  64.       ;;
  65.   esac
  66. }

  67. read net1
  68. net1=$(formatIP $net1)
  69. start1=$(IP2long ${net1%~*})
  70. end1=$(IP2long ${net1#*~})
  71. while read net2
  72. do
  73.   net2=$(formatIP $net2)
  74.   start2=$(IP2long ${net2%~*})
  75.   end2=$(IP2long ${net2#*~})
  76.   if [ $end1 -ge $end2 ];then
  77.           continue
  78.   elif [ $((end1+1)) -eq $start2 ];then
  79.     end1=$end2
  80.   else
  81.     cidr "$(long2IP $start1)~$(long2IP $end1)"
  82.     start1=$start2
  83.     end1=$end2
  84.   fi
  85. done
  86. cidr "$(long2IP $start1)~$(long2IP $end1)"
复制代码


用法:
./CIDR.sh < 数据文件

需求:数据文件是经过排序的。

[ 本帖最后由 springwind426 于 2008-7-14 15:00 编辑 ]

评分

参与人数 1可用积分 +1 收起 理由
liaosnet + 1 不错~

查看全部评分

论坛徽章:
0
3 [报告]
发表于 2008-07-14 14:48 |只看该作者

回复 #1 killua 的帖子

有点麻烦了,是不先要把网络段全都打印出来,如果有重复的则删除。

论坛徽章:
0
4 [报告]
发表于 2008-07-14 15:50 |只看该作者
原帖由 可可熊 于 2008-7-14 14:48 发表
有点麻烦了,是不先要把网络段全都打印出来,如果有重复的则删除。



应该是重复的删除,可以合并的则合并

如 202.88.64.0/18
202.88.120.0/22  
上面的是包含下面的,所以下面一行删除

合并的比如210.176.128.0/19
210.176.160.0/19

合并成 210.176.128.0/18

论坛徽章:
0
5 [报告]
发表于 2008-07-14 15:55 |只看该作者

回复 #4 killua 的帖子

没看二楼的代码,不知道行不。
真是比较麻烦。

论坛徽章:
0
6 [报告]
发表于 2008-07-14 16:32 |只看该作者
原帖由 springwind426 于 2008-7-14 14:42 发表
我自己写的一个脚本

CIDR.sh


#!/bin/bash
function IP2long(){
  local IFS='.'
  read IP1 IP2 IP3 IP4 = 8 ))
  NET=".$(( IP - (IP >> 8 > 8  




二楼猛的,我都看不懂,高手,高质量,拜读了。

谢谢二楼的兄弟

论坛徽章:
0
7 [报告]
发表于 2008-07-14 16:38 |只看该作者

回复 #6 killua 的帖子

果然很猛,试了一没问题。

论坛徽章:
0
8 [报告]
发表于 2008-07-15 00:20 |只看该作者
因为有合并网络的需求,恰好又在学习BASH,因此就写了一个脚本作为练手,肯定不是最简的表示方法  

论坛徽章:
0
9 [报告]
发表于 2008-07-15 00:47 |只看该作者

回复 #2 springwind426 的帖子

orz...

论坛徽章:
7
荣誉版主
日期:2011-11-23 16:44:17子鼠
日期:2014-07-24 15:38:07狮子座
日期:2014-07-24 11:00:54巨蟹座
日期:2014-07-21 19:03:10双子座
日期:2014-05-22 12:00:09卯兔
日期:2014-05-08 19:43:17卯兔
日期:2014-08-22 13:39:09
10 [报告]
发表于 2008-07-15 00:53 |只看该作者
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP