Chinaunix

标题: awk按取长度取值 [打印本页]

作者: linuxbody    时间: 2016-12-15 10:16
标题: awk按取长度取值
  1. ab<1.1.1.1> xxxxxxxx
  2. ab<1.1.1.2> xxxxxxxx
  3. 1234567
  4. 1234567
  5. 777 abc
  6. AB:ABC QQ 12d2,SMCowAAnbZ5zd1FYU1viC1
  7. AB:ABC AA 33d3,PMCowEA5Z1Ogd1FYstcIDA
复制代码
变成

  1. ab<1.1.1> xxxxxxxx 2
  2. 1234567 2
  3. 777 abc 1
  4. AB:ABC 2
复制代码


AB:ABC 后面的长度总是随机,想要awk一句话搞定试了很久不行,管道可以 但怕影响效率

作者: 聆雨淋夜    时间: 2016-12-15 10:24
处理规则是什么,文本就这么长吗
作者: moperyblue    时间: 2016-12-15 10:36

  1. awk '{if(/</){match($0,/(.*)\..*(>.*)/,a);k=a[1] a[2]}else if(/:/){k=$1}else{k=$0}}!b[k]++{d[++c]=k}END{while(i++<c)print d[i],b[d[i]]}' file
复制代码

作者: linuxbody    时间: 2016-12-15 11:56
回复 3# moperyblue

awk: line 1: syntax error at or near ,
作者: moperyblue    时间: 2016-12-15 11:59
本帖最后由 moperyblue 于 2016-12-15 12:01 编辑

回复 4# linuxbody

more  file
  1. ab<1.1.1.1> xxxxxxxx
  2. ab<1.1.1.2> xxxxxxxx
  3. 1234567
  4. 1234567
  5. 777 abc
  6. AB:ABC QQ 12d2,SMCowAAnbZ5zd1FYU1viC1
  7. AB:ABC AA 33d3,PMCowEA5Z1Ogd1FYstcIDA
复制代码

awk '{if(/</){match($0,/(.*)\..*(>.*)/,a);k=a[1] a[2]}else if(/:/){k=$1}else{k=$0}}!b[k]++{d[++c]=k}END{while(i++<c)print d,b[d]}' file
  1. ab<1.1.1> xxxxxxxx 2
  2. 1234567 2
  3. 777 abc 1
  4. AB:ABC 2
复制代码

作者: linuxbody    时间: 2016-12-15 12:11
回复 5# moperyblue

  1. AB:ABC 123 3x29,T8CowEB5k0R
  2. AB:ABC 321 a4x6,QsCowEB5gm2ud1FYmkShBg
  3. ab<1.1.1.1> hello
  4. ab<1.1.1.2> hello
  5. 123 HI^M\n\n\n
复制代码
抱歉,数据格式有误
  1. AB:ABC 2
  2. ab<1.1.1> 2
  3. 123 HI^M\n\n\n 1
复制代码



作者: moperyblue    时间: 2016-12-15 12:15
回复 6# linuxbody


不是你希望的结果吗? 你希望的结果是怎样?
作者: sunzhiguolu    时间: 2016-12-15 13:02
  1. perl -F/:/ -nle '{$_=@F%2?s/\.\d(?=>)//r:join(":",$F[0],(split(" ",$F[-1],2))[0]);$h{$_}++}END{print "$_ $h{$_}" for keys %h}' f
复制代码

作者: cjaizss    时间: 2016-12-15 13:02
感觉规则不明确,
ab<1.1.1> xxxxxxxx 2
这一行特别怪异
作者: linuxbody    时间: 2016-12-15 13:23
回复 7# moperyblue

结果是对的,gawk版本问题,感谢!
作者: linuxbody    时间: 2016-12-19 14:03
回复 5# moperyblue

  1. 777 ABC^M\n
  2. 777 ABC^M\n
  3. 777 ABC^M\n
复制代码
如果极端情况下出现这种特殊字符串怎么处理?
作者: moperyblue    时间: 2016-12-19 14:26
回复 11# linuxbody

1.文件大吗? 不大的话能否用sed之类的先预处理一下?

2.如果有这种,最终结果是:
777 ABC^M\n 3
还是
777 ABC 3
作者: linuxbody    时间: 2016-12-19 15:25
回复 12# moperyblue

我用sed先换掉了,急着要请教一下 awk做第二列次数统计,最后的总数怎么打印出来? {a[$2]++}END{for(b in a)print b,a,这里怎么类似写 a+=$0 END print a}

作者: moperyblue    时间: 2016-12-19 15:36
回复 13# linuxbody


  1. echo 'a
  2. b
  3. a
  4. b
  5. c'|awk '{a[$1]++}END{for(i in a){print i,a[i];s+=a[i]};print "总数:"s}'
复制代码

作者: sditmaner    时间: 2016-12-20 13:13
回复 5# moperyblue
作者: linuxbody    时间: 2016-12-20 16:23
回复 14# moperyblue

感谢!
作者: linuxbody    时间: 2016-12-26 13:59
本帖最后由 linuxbody 于 2016-12-26 14:02 编辑

回复 3# moperyblue
  1. awk '{if(/</){match($0,/(.*)\..*(>.*)/,a);k=a[1] a[2]}else if(/:/){k=$1}else{k=$0}}!b[k]++{d[++c]=k}END{while(i++<c)print d[i],b[d[i]]}' file
复制代码


编辑

  1. 请问怎么print出a+=b[d[i]]的值呢
复制代码





作者: moperyblue    时间: 2016-12-26 14:14
回复 17# linuxbody


  1. awk '{if(/</){match($0,/(.*)\..*(>.*)/,a);k=a[1] a[2]}else if(/:/){k=$1}else{k=$0}}!b[k]++{d[++c]=k}END{while(i++<c){print d[i],b[d[i]];s+=b[d[i]]};print "总数:"s}' file
复制代码

作者: linuxbody    时间: 2016-12-26 14:25
回复 18# moperyblue

可用,感谢如果不带“总数”这一行的结果里,能直接得到类似 sort -k1的排序吗

作者: moperyblue    时间: 2016-12-26 14:28
回复 19# linuxbody


你希望得到什么结果?
作者: moperyblue    时间: 2016-12-26 14:40

  1. awk '{if(/</){match($0,/(.*)\..*(>.*)/,a);k=a[1] a[2]}else if(/:/){k=$1}else{k=$0}}{b[k]++}END{for(i in b)print i,b[i]|"sort -k1"}' file
复制代码

?
作者: linuxbody    时间: 2016-12-26 14:56
回复 20# moperyblue

  1. root@debian:~# cat t
  2. ab<1.1.1.1> xxxxxxxx
  3. ab<1.1.1.2> xxxxxxxx
  4. 1234567
  5. 1234567
  6. 777 abc
  7. AB:ABC QQ 12d2,SMCowAAnbZ5zd1FYU1viC1
  8. AB:ABC AA 33d3,PMCowEA5Z1Ogd1FYstcIDA
  9. Ct tsize
  10. User deleted!
  11. root@debian:~# awk '{if(/</){match($0,/(.*)\..*(>.*)/,a);k=a[1] a[2]}else if(/:/){k=$1}else{k=$0}}!b[k]++{d[++c]=k}END{while(i++<c){print d[i],b[d[i]];s+=b[d[i]]};print "total:"s}' t |sort -k1
  12. 1234567 2
  13. 777 abc 1
  14. ab<1.1.1> xxxxxxxx 2
  15. AB:ABC 2
  16. Ct tsize 1
  17. total:9
  18. User deleted! 1
复制代码


希望得带的结果是这样:

  1. 1234567 2
  2. 777 abc 1
  3. ab<1.1.1> xxxxxxxx 2
  4. AB:ABC 2
  5. Ct tsize 1
  6. User deleted! 1

  7. total:9
复制代码



作者: moperyblue    时间: 2016-12-26 15:37
回复 22# linuxbody


  1. awk '{if(/</){match($0,/(.*)\..*(>.*)/,a);k=a[1] a[2]}else if(/:/){k=$1}else{k=$0}}{b[k]++}END{for(i in b){print i,b[i]|"sort -k1";s+=b[i]};print "\ntotal:"s}' file|awk 1
复制代码

作者: linuxbody    时间: 2016-12-26 16:32
回复 23# moperyblue

可用,结果是对的,我想问下awk 1 为什么会翻转?
作者: moperyblue    时间: 2016-12-26 16:59
本帖最后由 moperyblue 于 2016-12-26 17:08 编辑

回复 24# linuxbody


只是再经过一个管道 其实重定向到一个文件也是可以的
作者: moperyblue    时间: 2016-12-26 17:09
本帖最后由 moperyblue 于 2016-12-26 17:10 编辑

info awk

=>

       NOTE:  If using a pipe, co-process, or socket to getline, or from print
       or printf within a loop, you must use close() to create  new  instances
       of  the  command  or  socket.   AWK does not automatically close pipes,
       sockets, or co-processes when they return EOF.


作者: linuxbody    时间: 2016-12-27 11:20
回复 26# moperyblue

  1. SSH access denied. http://localhost:8080/ssh.php?s=1&&i=20&&n26
  2. SSH access denied. http://localhost:8080/ssh.php?s=3&&i=75&&n96
  3. SSH Time Out.  http://172.16.3.194:8080/ssh.php?k=2&&z=96
  4. Bad UserName.  http://172.16.3.194:8080/ssh.php?p=11&&z=23
  5. IP limited.  http://172.16.3.194:8080/xxxxx

  6. 如果后面有http,在现有的基础上怎么统计前排呢
复制代码


作者: moperyblue    时间: 2016-12-27 11:55
本帖最后由 moperyblue 于 2016-12-27 12:52 编辑

回复 27# linuxbody


这种你要统计进去吗? 如果是 希望结果是怎样?
如果不统计 在前面的步骤过滤掉这部分数据




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2