免费注册 查看新帖 |

Chinaunix

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

合并ip地址问题,哪位大神帮忙看看。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-10-12 23:29 |只看该作者 |倒序浏览
本帖最后由 chenwenming_zj 于 2013-10-12 23:30 编辑

如:

cat a.txt
192.168.1
192.168.2
192.168.3
172.19.3
192.16.1
192.16.2
10.0.4

想得到:
192.168.1-192.168.3
172.19.3
192.16.1-192.16.2
10.0.4


请问用awk 或perl 怎么写呀,我的思路是:
把$1.$2放到一个变量里,下一行的$1.$2与这个变量对比,如果相同进行下一个$3的对比,如果$3与上一个值差为1,继续对比直到不为1,打印出第一个$3与最后一次值,但还是没写出来,请教一下大家,谢了!

论坛徽章:
3
CU十二周年纪念徽章
日期:2013-10-24 15:41:34子鼠
日期:2013-12-14 14:57:19射手座
日期:2014-04-25 21:23:23
2 [报告]
发表于 2013-10-13 17:29 |只看该作者
如果出现192.168.6  192.168.8  这种不连续的 又该如何呢。。

论坛徽章:
0
3 [报告]
发表于 2013-10-13 19:02 |只看该作者
回复 2# mcshell


    如果不连续直接打印出来就行,主要是合并连续的部分。

论坛徽章:
3
CU十二周年纪念徽章
日期:2013-10-24 15:41:34子鼠
日期:2013-12-14 14:57:19射手座
日期:2014-04-25 21:23:23
4 [报告]
发表于 2013-10-13 22:11 |只看该作者
try回复 3# chenwenming_zj
  1. use strict;
  2. use warnings;
  3. my $h;
  4. map { /((?:\d+\.){2})(\d+)(?{push @{$h->{$1}},$2})/ } <DATA>;
  5. for my $k ( keys %$h ) {
  6.     my $str = join ",", sort { $a <=> $b } @{ $h->{$k} };
  7.     1 while ( $str =~
  8. s/(-)?(\d+)(?!\d),(\d++)(?(?{$3 != $2+1})(?!))/  $1 ?  "-$3" : "$2-$3" /e
  9.     );
  10.     print "$k$_\n" for ( split /,/, $str );
  11. }
  12. __DATA__
  13. 192.168.1
  14. 192.168.2
  15. 192.168.3
  16. 172.19.3
  17. 192.16.1
  18. 192.16.2
  19. 10.0.4
  20. 192.168.7
  21. 192.168.8
  22. 192.168.10
复制代码

论坛徽章:
0
5 [报告]
发表于 2013-10-14 00:44 |只看该作者
不明觉厉
s/(-)?(\d+)(?!\d),(\d++)(?(?{$3 != $2+1})(?!))/  $1 ?  "-$3" : "$2-$3" /e这个看了半天没看懂,
(-)?怎么理解,),(\d++)怎么理解,(?(?{$3 != $2+1})(?!)) 第一层的(?    )怎么理解,mcshell解释一下
看着你的签名头晕啊
回复 4# mcshell


   

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
6 [报告]
发表于 2013-10-14 00:53 |只看该作者
本帖最后由 rubyish 于 2013-10-13 21:26 编辑

如果:
  1. #!/usr/bin/perl
  2. my %h;

  3. print map {
  4.     my $k = $_;
  5.     my @a = sort { $a <=> $b } keys %{ $h{$k} };
  6.     my @b = [ shift @a ];
  7.     $_ - $b[-1][-1] > 1 && push @b, [$_] or $b[-1][1] = $_ for @a;
  8.     map $k . join( "-$k", @$_ ) . $/, @b;
  9. } sort do { map /(.*\.)(.*)/ && $h{$1}{$2}++, <DATA>; keys %h };

  10. __DATA__
  11. 192.168.1
  12. 192.168.2
  13. 192.168.3
  14. 172.19.3
  15. 192.16.1
  16. 192.16.2
  17. 10.0.4
  18. 192.168.1
  19. 192.168.5
  20. 192.168.7
复制代码

论坛徽章:
3
CU十二周年纪念徽章
日期:2013-10-24 15:41:34子鼠
日期:2013-12-14 14:57:19射手座
日期:2014-04-25 21:23:23
7 [报告]
发表于 2013-10-14 08:56 |只看该作者
回复 5# inchonline


    哈哈~~
   \d++保证第二个数字不会截断。
  (-)?,因为后面有可能做了替换"-",所以在此匹配的时候有可能有"-";
  (?(?{$3 != $2+1})(?!))  是一个if判断语句,如果$3不等于$2+1也就是不连续的时候,就强制回朔,如果没这个语句就会导致不连续的数字死循环,
  这里的(?!)等同于(*F),(*FAIL)具体可以参照perlre
   http://perldoc.perl.org/perlre.h ... cking-Control-Verbs{:3_200:}

  

论坛徽章:
3
CU十二周年纪念徽章
日期:2013-10-24 15:41:34子鼠
日期:2013-12-14 14:57:19射手座
日期:2014-04-25 21:23:23
8 [报告]
发表于 2013-10-14 09:28 |只看该作者
还可以换成这样的正则 ,感觉好理解些{:3_201:}
  1. use strict;
  2. use warnings;
  3. my $h;
  4. map { /((?:\d+\.){2})(\d+)(?{push @{$h->{$1}},$2})/ } <DATA>;
  5. for my $k ( keys %$h ) {
  6.     my $str = join ",", sort { $a <=> $b } @{ $h->{$k} };
  7. 1 while($str =~ s/(\d+)[,-]((?<=-)\d+|(?<=,)(??{$1+1})),((??{$2+1}))/$1-$3/g);
  8. $str =~ s/(\d+),((??{$1+1}))/$1-$2/g;
  9.     print "$k$_\n" for ( split /,/, $str );
  10. }
  11. __DATA__
  12. 192.168.1
  13. 192.168.2
  14. 192.168.3
  15. 172.19.3
  16. 192.16.1
  17. 192.16.2
  18. 10.0.4
  19. 192.168.7
  20. 192.168.8
  21. 192.168.10
复制代码

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
9 [报告]
发表于 2013-10-14 13:14 |只看该作者
本帖最后由 104359176 于 2013-10-14 13:15 编辑
  1. #!perl

  2. use 5.010;

  3. my @ips = <DATA>;
  4. my $init_ip = 0;
  5. my $first_mode = 0;
  6. my $last_ip = "";
  7. foreach my $ip (@ips) {
  8.         chomp $ip;
  9.         my $ip_number = $ip;
  10.         $ip_number =~ s/\.//g;
  11.         my $ip_step = abs($ip_number - $init_ip);
  12.         if ($ip_step > 1) {
  13.                 if ($first_mode == 1) { print "$last_ip\n$ip" }
  14.                 else { print "\n$ip" }
  15.                 $first_mode = 0;
  16.         }
  17.         elsif ($first_mode == 0) {
  18.                 print "-";
  19.                 $first_mode = 1;
  20.         }
  21.         $init_ip = $ip_number;
  22.         $last_ip = $ip;
  23. }

  24. __DATA__
  25. 192.168.1
  26. 192.168.2
  27. 192.168.3
  28. 172.19.3
  29. 192.16.1
  30. 192.16.2
  31. 10.0.4
复制代码
C:\WINDOWS\system32\cmd.exe /c perl hebin.pl

192.168.1-192.168.3
172.19.3
192.16.1-192.16.2
10.0.4
Hit any key to close this window...

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP