免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234
最近访问板块 发新帖
楼主: ansanchen
打印 上一主题 下一主题

请教一个shell高深的问题!跪谢! [复制链接]

论坛徽章:
0
31 [报告]
发表于 2006-04-15 17:49 |只看该作者
原帖由 非飞云 于 2006-4-14 23:07 发表
有点理解不了吖。。
既然可以把
58.32.0.0/13
58.40.0.0/15
58.42.0.0/16
58.43.0.0/16
58.44.0.0/14 合并成58.32.0.0/12

那我为什么不可以把所有58开头的合并为58.0.0.0/8 ?
以此类推 貌似答案无数吖 ...


比如:58.1.0.0/16并不在LZ列的IP范围之内,可是却在58.0.0.0/8的范围内

网络基础知识,稍微google一下吧

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
32 [报告]
发表于 2006-04-16 01:42 |只看该作者
參考本版另一貼子:
http://bbs.chinaunix.net/viewthread.php?tid=739988&extra=page%3D1
發現最後的版本還有改良的地方.

下面這個版本, 大家可以再測試看看:
  1. #!/bin/bash

  2. # get list file from $1 or default to ip.list
  3. file=${1:-ip.list}

  4. # function: to convert mask from /nn to /nnn.nnn.nnn.nnn
  5. convmask() {
  6.         # bit 1 is set to $1 and bit 0 is set to 32-$1
  7.         mask_bit=$(printf %.$1d 0 | tr 0 1)$(printf %.$((32-$1))d 0)
  8.         # devide 32 bits into 4 parts and convert to decimal
  9.         for i in 0 8 16 24; do
  10.                 mask_byte="${mask_bit:$i:8}"
  11.                 mask_dec=$(echo "ibase=2;$mask_byte" | bc)
  12.                 _mask="$_mask $mask_dec"
  13.         done
  14.         echo -n ${_mask:1}
  15.         unset mask_bit mask_dec _mask i
  16. }

  17. # function: calculate network address ( ip AND mask)
  18. calnet() {
  19.         # parameter 1-4 is IP, parameter 5-8 is mask
  20.         while [ $# -gt 4 ] ; do
  21.                 ip_dec=$(($1 & $5))
  22.                 _ip="$_ip.$ip_dec"
  23.                 shift 1
  24.         done
  25.         echo -n ${_ip:1}
  26.         unset ip_dec _ip
  27. }

  28. # function: to generate final network list
  29. listnet () {
  30.   count=0               # reset counter
  31.   ln=0                  # reset line number
  32.   last_ln=$#            # reset last line number

  33.   # start here
  34.   unset net_list
  35.   for subnet; do
  36.         ((ln++))        # count line number
  37.         ip=${subnet%/*}
  38.         mask=${subnet#*/}
  39.         # store last mask for current comparison
  40.         _last_mask=$last_mask
  41.         # store mask for next comparison
  42.         last_mask=$mask
  43.         # if at beginning or current mask is less than previous, skip comparison to previous
  44.         unset skip
  45.         [ $count = 0 ] || [ "$mask" -le "$_last_mask" ] || {
  46.                 # to determin if current network is a subnet of previous network
  47.                 testnet="$(calnet ${ip//./ } $(convmask $_last_mask) )/$_last_mask"
  48.                 # if yes, set mark
  49.                 [ "$testnet" = "$last_sub" ] &&  skip=1
  50.         }
  51.         # supernetting in 1 bit less
  52.         supermask=$((mask-1))
  53.         # invoke functions to have supernet unless current subnet is whithin previous
  54.         [ "$skip" = 1 ] || supernet="$(calnet ${ip//./ } $(convmask $supermask) )/$supermask"
  55.         # for first record only
  56.         [ $count = 0 ] && {
  57.                 last_sub=$subnet
  58.                 last_net=$supernet
  59.         }
  60.         # go next and increase counter if supernet is identical with previous
  61.         if [ "$last_net" = "$supernet" ] ; then
  62.                 ((count++))
  63.         # or to build list
  64.         else
  65.                 # use previous subnet if one line match only, or use previous supernet instead
  66.                 [ $count = 1 ] && net_list="$net_list $last_sub" || net_list="$net_list $last_net"
  67.                 # reset counter as well
  68.                 count=1
  69.         fi
  70.         # store subnet and supernet for next loop
  71.         last_sub=$subnet
  72.         last_net=$supernet
  73.         # for final line only
  74.         [ $ln = $last_ln ] && {
  75.                 # use previous network if counter is greater than 1, or use current network
  76.                 [ $count = 1 ] && net_list="$net_list $subnet" || net_list="$net_list $last_net"
  77.         }
  78.   done

  79.   # rebuild list in lines
  80.   net_list="$(echo ${net_list# } | tr ' ' '\n')"
  81.   # to have number of records
  82.   nr=$(echo "$net_list" | wc -l)
  83.   # redo the job if number in short
  84.   while [ "$nr" -lt $ln ]; do
  85.         listnet $net_list
  86.   done

  87. }

  88. listnet $(cat $file)

  89. # output
  90. echo "$net_list"

  91. exit 0
复制代码


執行結果:
  1. kenny@linux:~/tmp> cat 2.txt
  2. 193.58.204.0/22
  3. 193.58.208.0/22
  4. 193.193.160.0/22
  5. 193.193.168.0/22
  6. 193.243.164.0/22
  7. 194.126.128.0/22
  8. 194.126.132.0/22
  9. 194.126.134.0/23
  10. 194.151.128.0/19
  11. 195.42.240.0/21
  12. 195.240.0.0/16
  13. 195.241.0.0/16
  14. kenny@linux:~/tmp> ./cal_net.sh 2.txt
  15. 193.58.204.0/22
  16. 193.58.208.0/22
  17. 193.193.160.0/22
  18. 193.193.168.0/22
  19. 193.243.164.0/22
  20. 194.126.128.0/21
  21. 194.151.128.0/19
  22. 195.42.240.0/21
  23. 195.240.0.0/15
复制代码

[ 本帖最后由 網中人 于 2006-4-16 01:50 编辑 ]

论坛徽章:
0
33 [报告]
发表于 2006-04-16 09:05 |只看该作者
排序不是用sort吗??

论坛徽章:
0
34 [报告]
发表于 2006-04-16 23:12 |只看该作者

回复 32楼 網中人 的帖子

:)

论坛徽章:
0
35 [报告]
发表于 2006-04-17 09:53 |只看该作者
楼主的ip地址列表中
59.32.0.0/13 的地址范围是 59.32.0.0 59.39.255.255
59.40.0.0/15 的地址范围是 59.40.0.0 59.41.255.255
59.42.0.0/16 的地址范围是 59.42.0.0 59.42.255.255
这3个子网可以合并为一个超网地址写法就是
59.32.0.0/12 它的地址范围是  59.32.0.0 59.47.255.255
具体的算法可以参考网络基础中的子网和超网章节,或者看看CCNA中也有相关的讲解

所以
193.58.204.0/22 的地址范围是 193.58.204.0 193.58.207.255
193.58.208.0/22 的地址范围是 193.58.208.0 193.58.211.255
这两个是可以合并为超网的193.58.204.0/19 其ip地址范围是 193.58.192.0 193.58.223.255
为什么不能是 193.58.204.0/20 呢, 因为193.58.204.0/20的地址范围是193.58.192.0 193.58.207.255
不会包括193.58.208.0 193.58.211.255

呵呵,其实只要明白ip地址和掩码的划分原理就很容易理解了,其它一些问题我已在这个帖子中做了说明
http://bbs.chinaunix.net/viewthr ... &extra=page%3D1

[ 本帖最后由 slash001 于 2006-4-17 10:33 编辑 ]

论坛徽章:
0
36 [报告]
发表于 2006-04-17 11:30 |只看该作者
用shell是不是太变态了。用Python很容易。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
37 [报告]
发表于 2006-04-17 13:50 |只看该作者
原帖由 shhgs 于 2006-4-17 11:30 发表
用shell是不是太变态了。用Python很容易。


是啊, 有些東西, 用 shell 來寫并不好用.
不過, 這裡是 shell 版, 自然會討論 shell 的方案(故且不論方案的好壞).
再來, 因為前幾天在醫院陪老婆, 又不能上網, 也就找些"作業"來做做囉...  ^_^
現在回家了, 也就沒時間再來思考這個練習了, 雖然要改的地方還很多, 不足處還請原諒.

若樓主能順便提出 python 的方案的話, 應該是很有正面幫助的.
當然, 這個不強求啦. 畢竟大家都各有所忙.
除非是真的想打法時間, 或工作所需, 否則, 也沒必要殘害自己的腦細胞...  ^_^

论坛徽章:
0
38 [报告]
发表于 2006-04-18 13:05 |只看该作者

回复 37楼 網中人 的帖子

看来用SHELL可以做出来~~
感谢~~感谢,我先学习一下这个shell代码~OHOH

论坛徽章:
0
39 [报告]
发表于 2006-04-18 13:33 |只看该作者

请各位老大看看我运行时出现的错误提示

./new-ipagg.sh: line 1: printf: `-': invalid format character
./new-ipagg.sh: line 1: printf: `-': invalid format character
./new-ipagg.sh: line 1: printf: `-': invalid format character
./new-ipagg.sh: line 1: printf: `-': invalid format character
58.25.64.0/18
58.30.0.0/15
58.32.0.0/16
58.32.0.0/14
0.0.0.0/-2


数据文件如下:
more ip.list
58.25.64.0/18
58.30.0.0/15
58.32.0.0/16
58.32.0.0/14
58.32.0.0/13
58.36.0.0/14
58.40.0.0/15
58.43.0.0/16
58.44.0.0/14
58.48.0.0/14
58.48.0.0/13
58.52.0.0/14
58.56.0.0/19
58.56.0.0/15
58.56.32.0/19
58.57.0.0/16
58.59.128.0/19
58.59.128.0/17
58.59.160.0/19
58.59.192.0/18
58.60.0.0/15
58.60.0.0/14
58.62.0.0/15
58.66.0.0/15
58.82.0.0/17
58.82.140.0/22
58.82.144.0/20
58.82.160.0/19
58.82.192.0/20
58.82.192.0/19
58.82.208.0/20
58.82.224.0/20
58.82.240.0/21
58.82.240.0/20
58.82.248.0/21
58.100.0.0/16
58.208.0.0/12
58.215.254.0/23
58.216.254.0/23
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP