免费注册 查看新帖 |

Chinaunix

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

[文本处理] awk问题请教:2个文件的比较 [复制链接]

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
11 [报告]
发表于 2013-01-16 19:59 |只看该作者
看一下我这个如何,我这里没有中文环境,所以把你的中文都替换成拼音了。命令如下:
  1. awk -F "[ .]+" '{s=$1"."$2"."$3}NR==FNR{a[s,++b[s]]=$4","$8","$9;next}{for(i=1;i<=b[s];i++){split(a[s,i],c,",");if($4>=c[1]&&$4<=c[2]){print $0"\t"c[3];next}}}' b a
复制代码
执行效果如下:
  1. [root@localhost ~]# cat a
  2. 1.1.1.10     20
  3. 1.1.1.34     25
  4. 2.2.2.100   30
  5. 3.3.3.20     40
  6. [root@localhost ~]# cat b
  7. 1.1.1.0    1.1.1.31     caiwuyibu
  8. 1.1.1.32   1.1.1.63    caiwuerbu
  9. 2.2.2.0    2.2.2.127   jishubu
  10. 3.3.3.0    3.3.3.63     renshibu
  11. [root@localhost ~]# awk -F "[ .]+" '{s=$1"."$2"."$3}NR==FNR{a[s,++b[s]]=$4","$8","$9;next}{for(i=1;i<=b[s];i++){split(a[s,i],c,",");if($4>=c[1]&&$4<=c[2]){print $0"\t"c[3];next}}}' b a
  12. 1.1.1.10     20 caiwuyibu
  13. 1.1.1.34     25 caiwuerbu
  14. 2.2.2.100   30  jishubu
  15. 3.3.3.20     40 renshibu
  16. [root@localhost ~]#
复制代码

论坛徽章:
0
12 [报告]
发表于 2013-01-16 20:23 |只看该作者
可能是我的版本有问题,我用这个脚本居然啥也出不来。我用的是cygwin。

仍然非常感谢!

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
13 [报告]
发表于 2013-01-17 13:42 |只看该作者
回复 3# Shell_HAT

你的结果和lz的输出有点差异,看来偷懒是不行的,哈:
1.1.1.10     20 财务二部
1.1.1.34     25 财务二部
2.2.2.100   30 技术部
3.3.3.20     40 人事部
   

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
14 [报告]
发表于 2013-01-17 15:21 |只看该作者
我这个是在 cygwin 下测试通过的。效率可能不高,如果 lz 有兴趣,可以做如下改进:将数据存放方式改成平衡树,这样查找起来就快多了;或者将查找改为二分查找,也能将O(n)的复杂度降到O(log(n))。
  1. [seesea@UC ~] # bash --version
  2. GNU bash, version 2.05b.0(1)-release (i686-pc-cygwin)
  3. Copyright (C) 2002 Free Software Foundation, Inc.

  4. [seesea@UC ~] # awk -f cc.awk b a
  5. 1.1.1.10     20 财务一部
  6. 1.1.1.34     25 财务二部
  7. 2.2.2.100   30 技术部
  8. 3.3.3.20     40 人事部

  9. [seesea@UC ~] # cat a
  10. 1.1.1.10     20
  11. 1.1.1.34     25
  12. 2.2.2.100   30
  13. 3.3.3.20     40
  14. [seesea@UC ~] # cat b
  15. 1.1.1.0    1.1.1.31     财务一部
  16. 1.1.1.32   1.1.1.63    财务二部
  17. 2.2.2.0    2.2.2.127   技术部
  18. 3.3.3.0    3.3.3.63     人事部
  19. [seesea@UC ~] # cat cc.awk
  20. FNR==NR {
  21.     add_dept_info($1, $2, $3)
  22. }

  23. FNR == 1 && NR != 1 {
  24.     sort_dept_info()
  25. }

  26. FNR < NR {
  27.     print $0 OFS find_dept($1)
  28. }

  29. function atoinet(ip, __ARGEND__, ret)
  30. {
  31.     n = split(ip, ar, ".")
  32.     for (i = 1; i <= n; ++i)
  33.     {
  34.         ret = ret*256 + ar[i]
  35.     }

  36.     return ret
  37. }

  38. function add_dept_info(ip_start, ip_end, dept_name)
  39. {
  40.     dept_info[atoinet(ip_start)]   = dept_name
  41.     dept_info[atoinet(ip_end) - 1] = dept_name
  42. }

  43. function sort_dept_info()
  44. {
  45.     count = asorti(dept_info, sorted_index)
  46. }

  47. function find_dept(ip)
  48. {
  49.     inet = atoinet(ip)
  50.     for (i = count; i >= 1; --i)
  51.     {
  52.         if (inet >= sorted_index[i])
  53.             return dept_info[sorted_index[i]]
  54.     }

  55.     return "UNDEFINED"
  56. }
复制代码

论坛徽章:
0
15 [报告]
发表于 2013-01-17 16:22 |只看该作者
本帖最后由 jils2013 于 2013-01-17 16:25 编辑

和楼上的部分处理逻辑类似
  1. [root@localhost ~]# cat a
  2. 1.1.1.10     20
  3. 1.1.1.34     25
  4. 2.2.2.100   30
  5. 3.3.3.20     40
  6. [root@localhost ~]# cat b
  7. 1.1.1.0    1.1.1.31     C1
  8. 1.1.1.32   1.1.1.63    C2
  9. 2.2.2.0    2.2.2.127   T
  10. 3.3.3.0    3.3.3.63     R
  11. [root@localhost ~]# awk 'function gi(str)
  12. >       {split(str,sa,".");i=sa[1]*255^3+sa[2]*255^2+sa[3]*255+sa[4];return i}
  13. >      BEGIN\
  14. >       {while(getline <"a"){i=gi($1);a[i]=$2;c[i]=$1;}}
  15. >       {b=gi($1);e=gi($2);for(dep=b;dep<=e;dep++){if(dep in a)print c[dep],a[dep],$3}}' b
  16. 1.1.1.10 20 C1
  17. 1.1.1.34 25 C2
  18. 2.2.2.100 30 T
  19. 3.3.3.20 40 R
  20. [root@localhost ~]#
复制代码

论坛徽章:
33
ChinaUnix元老
日期:2015-02-02 08:55:39CU十四周年纪念徽章
日期:2019-08-20 08:30:3720周年集字徽章-周	
日期:2020-10-28 14:13:3020周年集字徽章-20	
日期:2020-10-28 14:04:3019周年集字徽章-CU
日期:2019-09-08 23:26:2519周年集字徽章-19
日期:2019-08-27 13:31:262016科比退役纪念章
日期:2022-04-24 14:33:24
16 [报告]
发表于 2013-01-17 23:27 |只看该作者
回复 13# seesea2517


    我写代码的时候楼主顶楼数据不是这个样子滴,现在的样子是后来改的

论坛徽章:
0
17 [报告]
发表于 2013-01-18 08:56 |只看该作者
回复 16# Shell_HAT
需求变更。。。

   

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
18 [报告]
发表于 2013-01-18 09:09 |只看该作者
回复 16# Shell_HAT


    原来是这样,一个小小的帖子居然也有项目的影子,lz 是做产品或是策划的吧,哈哈。

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
19 [报告]
发表于 2013-01-18 09:10 |只看该作者
回复 16# Shell_HAT


    可是我看出楼主的意思了,不然他就没必要写两个IP地址了,直接写个网络地址就好了~

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
20 [报告]
发表于 2013-01-18 09:14 |只看该作者
回复 15# jils2013


    有点类似,还是区别很大呢。因为lz说a文件很大,所以我没敢把a文件全部读进内存,而是把b文件读进内存做检索。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP