免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3877 | 回复: 14

请问怎么分类以下字段  关闭 [复制链接]

论坛徽章:
0
发表于 2004-05-23 18:54 |显示全部楼层
有这么一段字符

逗号后面的数字是user的某个记数(只有星期后面是逗号,其余都是空格分隔,user1,user2...是用户姓名)

2004 May 23 Sun,       8         user4
2004 May 23 Sun,       7         user8
2004 May 23 Sun,       3         user1
2004 May 23 Sun,       1         user5
2004 May 23 Sun,       1         user3
2004 May 22 Sat,       3         user1
2004 May 22 Sat,       3         user5
2004 May 22 Sat,      10         user4
2004 May 21 Fri,       6         user3
2004 May 21 Fri,       2         user2
2004 May 21 Fri,       1         user6
2004 May 21 Fri,       1         user5
2004 May 21 Fri,      15         user4
2004 May 21 Fri,      10         user1
2004 May 20 Thu,       4         user1
2004 May 20 Thu,       2         user3
2004 May 20 Thu,      20         user4
2004 May 20 Thu,       1         user2
2004 May 19 Wed,       5         user1
2004 May 19 Wed,       4         user7
2004 May 19 Wed,       4         user3
2004 May 19 Wed,      21         user4
2004 May 18 Tue,       8         user3
2004 May 18 Tue,       4         user2
2004 May 18 Tue,       2         user5
2004 May 18 Tue,       1         user7
2004 May 18 Tue,      10         user1
2004 May 17 Mon,       8         user1
2004 May 17 Mon,       2         user3
2004 May 17 Mon,       2         user2
2004 May 17 Mon,       1         user5


请问如何将这段字符改为以时间为分类,统计出每个user在同一天里面的次数。以下是期望得到的结果:

2004 May 23 Mon,

       user1    1
       user2    3
       user3   10

2004  May 22 Tue,

       user1    11
       user2    23
       user3   12

...

麻烦热心人指教。  

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
发表于 2004-05-23 21:31 |显示全部楼层

请问怎么分类以下字段

  1. sort -r -k3 a|awk '{a[$1 $2 $3 $6]+=$5}END{for(i in a){split(i,b,"");printf"%s%d\n",i,a[i]}}' a|sort -r|sed 's/^\(....\)\(...\)\(..\)\([^ ]\+\) \(.*\)/\1 \2 \3 \4 \5/'|awk '{if($1$2$3==a){printf("%s %d\n",$4,$5)}else{printf("%s %s %s\n%s%d\n",$1,$2,$3,$4,$5);a=$1$2$3;b=$0}}'
复制代码

注意所有代码在同一行。代码有点乱
测试结果
  1. 2004 May 23
  2. user8 7
  3. user5 1
  4. user4 8
  5. user3 1
  6. user1 3
  7. 2004 May 22
  8. user5 3
  9. user4 10
  10. user1 3
  11. 2004 May 21
  12. user6 1
  13. user5 1
  14. user4 15
  15. user3 6
  16. user2 2
  17. user1 10
  18. 2004 May 20
  19. user4 20
  20. user3 2
  21. user2 1
  22. user1 4
  23. 2004 May 19
  24. user7 4
  25. user4 21
  26. user3 4
  27. user1 5
  28. 2004 May 18
  29. user7 1
  30. user5 2
  31. user3 8
  32. user2 4
  33. user1 10
  34. 2004 May 17
  35. user5 1
  36. user3 2
  37. user2 2
  38. user1 8
复制代码

论坛徽章:
0
发表于 2004-05-23 21:41 |显示全部楼层

请问怎么分类以下字段

[quote]原帖由 "admirer"][/quote 发表:


不知道该说什么好。。。。真的是很感谢了 ~~ 我现在就试试!

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
发表于 2004-05-23 21:47 |显示全部楼层

请问怎么分类以下字段

修改一下(剔除测试时得多余代码):
  1. sort -r -k3 filename | awk '{a[$1 $2 $3 $6]+=$5}END{for(i in a){printf"%s  %d\n",i,a[i]}}' |sort -r|sed 's/^\(....\)\(...\)\(..\)\([^ ]\+\) \(.*\)/\1 \2 \3 \4 \5/'|awk '{if($1$2$3==a){printf("%s %d\n",$4,$5)}else{printf("\n%s %s %s\n\n%s %d\n",$1,$2,$3,$4,$5);a=$1$2$3;b=$0}}'
复制代码

仍然是一行代码!

论坛徽章:
0
发表于 2004-05-23 22:35 |显示全部楼层

请问怎么分类以下字段

[quote]原帖由 "admirer"][/quote 发表:


看了您的代码有几个不清楚的地方想问以下。

1.在您的代码中 for(i in a) 就是看a 里面有几行,那么有其他方法通过awk来计算行数的吗?

2.(在线还在考虑中...)

谢谢

论坛徽章:
0
发表于 2004-05-23 22:36 |显示全部楼层

请问怎么分类以下字段

[quote]原帖由 "admirer"][/quote 发表:



看了您的代码有几个不清楚的地方想问一下。

首先我的理解是:

在数组 a[]中的一个例子:

a = value  ==>  a[2004May18user1]=4


我的问题是:

1.在您的代码中 for(i in a) 就是看a 里面有几行,那么有其他方法通过awk来计算行数的吗?

2.split() 函数的运用

(在线还在考虑中...)

谢谢

论坛徽章:
0
发表于 2004-05-23 23:35 |显示全部楼层

请问怎么分类以下字段

终于写好了,呵呵。最新更新在 http://linux.dalouis.com/computer/linux/nullida.html

这个脚本可以从 qmail-scanner 的 qmail-queue.log 文档中找出类似于以下的行

  1. Wed, 19 May 2004 17:31:15 CST:25176: g_e_h: return-path is "user1@domain1.com", recips is "user2@domain2.com"
复制代码


然后根据用户和时间来统计用户的使用量,变量$DOMAIN是你自己的服务器名,也就是上句中的 @domain1.com 或者 @domain2.com

  1. awk '/return-path/&&$10~/''$DOMAIN/&&$13!~/'$DOMAIN'/  {print ":"$4,$3,$2,$1":"gensub(/\"(.*)@.*\",/,"\\1",1,$10)}' /var/spool/qmailscan/qmail-queue.log  | sort | uniq -c | awk -F: '{print $2":"$1":"$3}' | sort -nr +0 -3 | awk -F: '{array_a[$1 $3]+=$2}END{for(i in array_a){split(i,array_b,"");printf"%s,%d\n",i,array_a[i]}}' |sort -r | awk -F, '{if($1==date){printf("\t%d\t%s\n",$3,$2)}else{printf("%s\n\t%d\t%s\n",$1,$3,$2);date=$1;array_b=$0}}'
复制代码


非常感谢admirer,我对您的代码进行了一点点改动。 
把 
  1. 2004 May 21 Fri, 1 user6
复制代码


分为了 
  1. 2004 May 21 Fri, : 1 : user6
复制代码
三组 $1 $2 $3,
然后进行split , 然后再利用星期里面自带的逗号,用printf"%s,%d\n"添加了一个逗号使之成为 
  1. 2004 May 21 Fri, 1 , user6
复制代码
最后打印输出。

运算结果:

http://linux.dalouis.com/log/mail_sender.txt


  1. 2004 May 23 Sun
  2.         7        user4
  3.         3        user1
  4.         1        user3
  5.         14        user2
  6.         1        user6
  7. 2004 May 22 Sat
  8.         3        user1
  9.         3        user3
  10.         10        user2
  11. 2004 May 21 Fri
  12.         10        user1
  13.         1        user7
  14.         1        user3
  15.         15        user2
  16.         6        user6
  17.         2        user5
  18. 2004 May 20 Thu
  19.         4        user1
  20.         20        user2
  21.         2        user6
  22.         1        user5
  23. 2004 May 19 Wed
  24.         5        user1
  25.         4        kreny
  26.         21        user2
  27.         4        user6
  28. 2004 May 18 Tue
  29.         10        user1
  30.         1        kreny
  31.         2        user3
  32.         8        user6
  33.         4        user5
  34. 2004 May 17 Mon
  35.         8        user1
  36.         1        user3
  37.         2        user6
  38.         2        user5
复制代码


一篇值得参考的文章
Split a string into an array
http://www.starlink.rl.ac.uk/star/docs/sc4.htx/node38.html

论坛徽章:
0
发表于 2004-05-24 00:10 |显示全部楼层

请问怎么分类以下字段

请教admirer:

awk 用 for (value in array) 输出时,排序太麻烦了,有什么好办法?

论坛徽章:
0
发表于 2004-05-24 00:44 |显示全部楼层

请问怎么分类以下字段

原帖由 "Mercury_cn" 发表:
请教admirer:

awk 用 for (value in array) 输出时,排序太麻烦了,有什么好办法?


我觉得在喂它之前就排好序列比较好。而且可能要用-n (以数字形式)。

论坛徽章:
0
发表于 2004-05-24 02:03 |显示全部楼层

请问怎么分类以下字段

原帖由 "jackieyuan" 发表:


我觉得在喂它之前就排好序列比较好。而且可能要用-n (以数字形式)。


你没明白我的意思.我指的是AWK输出数组时的排序.喂它这前排序不能解决问题,一用for输出就乱了.


我刚才又仔细看了一下你这个文本,很奇怪,你说"逗号后面的数字是user的某个记数",既然是记数了,应该在一个日期下每个USER只有一个记录,可能不用统计,可我不知道你的真正需求,就把你的原文本(看这个应该不用再统计了直接输出就行)的行数复制了一次(行数加了一倍,一个日期下出现重复用户记录,肯定要统计了),分别测试了一下,没用数组,这样反而避免了数组输出时乱序,一次sort加一次awk就可以:

原文本(31行)的测试:
44P.midtst:/midtst/tmp > sort -k3,3r -k6,6 bb | awk '{if(sDate!=substr($0,1,15)){print substr($0,1,15);sDate=substr($0,1,15)};print $6,$5}'
2004 May 23 Sun
user1 3
user3 1
user4 8
user5 1
user8 7
2004 May 22 Sat
user1 3
user4 10
user5 3
2004 May 21 Fri
user1 10
user2 2
user3 6
user4 15
user5 1
user6 1
2004 May 20 Thu
user1 4
user2 1
user3 2
user4 20
2004 May 19 Wed
user1 5
user3 4
user4 21
user7 4
2004 May 18 Tue
user1 10
user2 4
user3 8
user5 2
user7 1
2004 May 17 Mon
user1 8
user2 2
user3 2
user5 1
44P.midtst:/midtst/tmp >


结果同ADMIRER的一致,同时用户名也排序了.而且因为没考虑统计,代码短了

有重复记录文本(62行)的测试:

44P.midtst:/midtst/tmp > sort -k3,3r -k6,6 b | awk '{if(sDate!=substr($0,1,15)){if(NR!=1){print sUser,iCnt;}print substr($0,1,15);sDate=substr($0,1,15);iCnt=$5;sUser=$6;}else{if(sUser!=$6){print sUser,iCnt;iCnt=$5;sUser=$6}else iCnt+=$5};};END{print sUser,iCnt}'
2004 May 23 Sun
user1 6
user3 2
user4 16
user5 2
user8 14
2004 May 22 Sat
user1 6
user4 20
user5 6
2004 May 21 Fri
user1 20
user2 4
user3 12
user4 30
user5 2
user6 2
2004 May 20 Thu
user1 8
user2 2
user3 4
user4 40
2004 May 19 Wed
user1 10
user3 8
user4 42
user7 8
2004 May 18 Tue
user1 20
user2 8
user3 16
user5 4
user7 2
2004 May 17 Mon
user1 16
user2 4
user3 4
user5 2
44P.midtst:/midtst/tmp >


每行统计数结果是原文本的二倍

我上面的脚本是为了好抓屏运行时从VIM里把写好的脚本合成一行后抓到命令行的,贴上脚本:

  1. #### 原文本 ####

  2. sort -k3,3r -k6,6 b | awk '{
  3.    if(sDate!=substr($0,1,15))
  4.    {
  5.       print substr($0,1,15);
  6.       sDate=substr($0,1,15);
  7.    }
  8.    print $6,$5;
  9. }'

  10. #### 新文本 ####

  11. sort -k3,3r -k6,6 b | awk '{
  12.    if(sDate!=substr($0,1,15))
  13.    {
  14.       if(NR!=1)
  15.       {
  16.          print sUser,iCnt;
  17.       }
  18.       print substr($0,1,15);
  19.       sDate=substr($0,1,15);
  20.       iCnt=$5;sUser=$6;
  21.    }
  22.    else
  23.    {
  24.       if(sUser!=$6)
  25.       {
  26.          print sUser,iCnt;
  27.          iCnt=$5;sUser=$6;
  28.       }
  29.       else iCnt+=$5;
  30.    };
  31. };
  32. END{print sUser,iCnt}'
复制代码


为什么发帖时CODE中不能嵌COLOR! 高手赐教!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

DTCC2020中国数据库技术大会

【架构革新 高效可控】2020年12月21日-23日第十一届中国数据库技术大会将在北京隆重召开。

大会设置2大主会场,20+技术专场,将邀请超百位行业专家,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨,为广大数据领域从业人士提供一场年度盛会和交流平台。

http://dtcc.it168.com


大会官网>>
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP