Chinaunix

标题: 去重复-新情况 [打印本页]

作者: yinyuemi    时间: 2011-02-23 03:00
标题: 去重复-新情况
本帖最后由 yinyuemi 于 2011-02-23 04:52 编辑

今天在“The UNIX and Linux Forums”上看到一个关于去重复的帖子,觉得以前没有看过这样的例子,大家可以练练手:>

  1. cat file

  2. 2 B:M 17
  3. 3 M:B 16
  4. 4 B:M 15
  5. 5 M:B 14
  6. 6 M:B 13
  7. 7 B:M 11
  8. 9 B:M 27
  9. 10 B:M 26
  10. 11 M:B 25
  11. 13 B:M 6
  12. 14 B:M 5
  13. 15 M:B 4
  14. 16 B:M 3
  15. 17 M:B 2
  16. 19 A:M 3
  17. 22 A:B 14
  18. 23 A:M 6
  19. 24 A:B 13
  20. 25 B:M 11
  21. 26 M:B 10
复制代码
2 B:M 17 和 17 M:B 2
3 M:B 16 和 16 B:M 3
……
为重复,要求是保留第一个,除去第二个。

下面是我写的,觉得不够简练,应该还能更简练
  1. awk -F"[:| ]" '{a[$1$2$3$4]=1;b[NR]=$0}{if($4$3$2$1 in a) c[NR]=1}END{for(i=1;i<=NR;i++) {if(!(i in c)) print b[i]}}' file
复制代码

作者: expert1    时间: 2011-02-23 10:08
up,没什么思路,
作者: jason680    时间: 2011-02-23 10:35
今天在“The UNIX and Linux Forums”上看到一个关于去重复的帖子,觉得以前没有看过这样的例子,大家可以练 ...
yinyuemi 发表于 2011-02-23 03:00


awk -F"[: ]" '{if(!(a[$4$3$2$1]==1||a[$1$2$3$4]==1))print;a[$1$2$3$4]=1}' file
作者: yinyuemi    时间: 2011-02-23 10:42
awk -F"[: ]" '{if(!(a[$4$3$2$1]==1||a[$1$2$3$4]==1))print;a[$1$2$3$4]=1}' file
jason680 发表于 2011-02-23 10:35



    赞!!!

你的还可以在精炼一下
  1. awk -F"[: ]" '!(a[$4$3$2$1]||a[$1$2$3$4]){print;a[$1$2$3$4]=1}' file
复制代码

作者: jason680    时间: 2011-02-23 10:55
回复 4# yinyuemi


意思到了就好了.....
再精练只是字数(code长度)问题,没有多大意义....

相同思维...(改用正向判断与next)
awk -F"[: ]" '{if(a[$4$3$2$1]||a[$1$2$3$4])next;print;a[$1$2$3$4]=1}' file
作者: miniqq    时间: 2011-02-23 11:01
如果所谓的“重复” 就是 “直接反转” ,那没什么意思!
作者: ywlscpl    时间: 2011-02-23 13:22
本帖最后由 ywlscpl 于 2011-02-23 13:25 编辑
  1. awk -F '[: ]+' '!a[$4$3$2$1]++;{a[$1$2$3$4]++}' file
复制代码
正向重复和逆向重复都去
作者: yinyuemi    时间: 2011-02-23 13:57
正向重复和逆向重复都去
ywlscpl 发表于 2011-02-23 13:22



    学习,多谢白云苍狗兄!
作者: chenbin200818    时间: 2011-02-24 11:44
回复 7# ywlscpl


    这样写 更清晰点

awk -F '[: ]+' '!a[$4$3$2$1]++;{print ;a[$1$2$3$4]=1}' file
作者: cjaizss    时间: 2011-02-24 13:29
sed的

  1. sed -rn '/^[ \t]*$/d;H;x;s/[ \t]//g;
  2. /\n([^\n]+)(.):(.)([^\n]+)\n(.*\n)?(\1\2:\3\4|\4\3:\2\1)$/{x;d;};x;p' urfile
复制代码

作者: davidbeckham921    时间: 2011-02-24 14:51
学习!~~厉害!~~
作者: yinyuemi    时间: 2011-02-24 15:48
sed的
cjaizss 发表于 2011-02-24 13:29



    cjaizss兄,可以解释下这是什么用法?
"?()"是对前面正则的判断么?多谢!
/\n([^\n]+)(.).)([^\n]+)\n(.*\n)?(\1\2:\3\4|\4\3:\2\1)$/
作者: cjaizss    时间: 2011-02-24 15:49
cjaizss兄,可以解释下这是什么用法?
"?()"是对前面正则的判断么?多谢!
/\n([^\n]+)(.).)([^\ ...
yinyuemi 发表于 2011-02-24 15:48



    问号不是regex中很正常的用法吗?
作者: yinyuemi    时间: 2011-02-24 16:27
回复 13# cjaizss


    这个明白,

只是这段匹配看的有点晕,
我测试了下
/\n([^\n]+)(.).)([^\n]+)\n(.*\n)?(\4\3:\2\1)$/
/\n([^\n]+)(.).)([^\n]+)\n(.*\n)(\4\3:\2\1)$/
/\n([^\n]+)(.).)([^\n]+)\n(.*\n)?(\1\2:\3\4|\4\3:\2\1)$/
得出的结果都一样,


另外,是否这段代码对文件中数据的排列有关?比如:
  1. cat file1
  2. 3 M:B 16
  3. 5 M:B 14
  4. 14 B:M 5
  5. 15 M:B 4
  6. 16 B:M 3

  7. sed -rn 'H;x;s/[ \t]//g;
  8. /\n([^\n])(.):(.)([^\n]+)\n(.*)?(\1\2:\3\4|\4\3:\2\1)$/{x;d;};x;p' file1
  9. 3 M:B 16
  10. 5 M:B 14
  11. 15 M:B 4

  12. cat file2
  13. 14 B:M 5
  14. 15 M:B 4
  15. 16 B:M 3
  16. 3 M:B 16
  17. 5 M:B 14

  18. sed -rn 'H;x;s/[ \t]//g;
  19. /\n([^\n])(.):(.)([^\n]+)\n(.*)?(\1\2:\3\4|\4\3:\2\1)$/{x;d;};x;p' file
  20. 14 B:M 5
  21. 15 M:B 4
  22. 16 B:M 3
  23. 3 M:B 16
  24. 5 M:B 14
复制代码

作者: cjaizss    时间: 2011-02-24 16:49
回复  cjaizss


    这个明白,

只是这段匹配看的有点晕,
我测试了下
/\n([^\n]+)(.).)([^\n]+) ...
yinyuemi 发表于 2011-02-24 16:27



    语意和我的不一样,数据不同的情况下会出错
作者: longxibendi    时间: 2011-02-25 03:10
回复 1# yinyuemi


    让我做,只能用两个循环了,外面用 for  ,里面用 awk进行处理,相当于两个循环。复杂度很大。
作者: ontherd    时间: 2011-02-25 11:42
高人在交谈,学习下。
作者: 南极雨    时间: 2011-02-25 12:11
uniq
作者: gaoyan0705    时间: 2011-12-14 11:51
我有awk的问题,谁有时间啊,请教一下
作者: cjaizss    时间: 2011-12-14 13:14
这个题目我见过的,本版以前就有人讨论过的,只是帖子太多,找不到了
作者: dragon23452345    时间: 2012-05-09 15:53
提示: 作者被禁止或删除 内容自动屏蔽
作者: xiaochuanjiejie    时间: 2013-03-06 13:45
ywlscpl 发表于 2011-02-23 13:22
正向重复和逆向重复都去


可以讲解下  '!a[$4$3$2$1]++;{a[$1$2$3$4]++}' 的含义吗,谢谢
作者: yestreenstars    时间: 2013-03-06 19:42
本帖最后由 yestreenstars 于 2013-03-07 10:07 编辑

我只看了前面几个回复,貌似这样更简洁?
  1. awk -F '[ :]' '{a[$1$2$3$4]}!($4$3$2$1 in a)'
复制代码

作者: cao627    时间: 2013-03-06 21:09
回复 22# xiaochuanjiejie
可以讲解下  '!a[$4$3$2$1]++;{a[$1$2$3$4]++}' 的含义吗,谢谢


awk    '1'         file              # 永远打印file中awk当前读到的记录.
awk    '1;{}'   file             #永远打印file中awk当前读到的记录,然后执行{}中的内容,但  {}中为空,所以什么也没有执行。
awk    '!1;{}'   file            #永远打印file中awk当前读到的记录,然后执行{}中的内容,但  {}中为空,所以什么也没有执行。
awk    '!a;{a=1}'   file     #如果a为0或空则打印awk当前读到的记录,否者不打印,不管打印还是不打印,都执行{}中的a=1.




awk    '!a[$4$3$2$1];{a[$1$2$3$4]=1}'   file

如果awk读到file第一记录是 “a b c d”,则 a[$4$3$2$1] == a[dcba],由于a[dcba]是第 一次出现,所以是为空,所以!a[$4$3$2$1] == 1, 打印该行 a b c d,然后执行a[$1$2$3$4]=1,即a[abcd]=1。
然后awk继续读file的第二条记录。如果第二条记录是 “d c b a”,则 a[$4$3$2$1] == a[abcd],由于a[abcd]这个数组(严格说叫散列)在读第一条记录时已经赋值为1,所以!a[$4$3$2$1] == 0,当前读到的这第二条记录就不被打印。


awk    '!a[$4$3$2$1]++;{a[$1$2$3$4]++}'   file  同理。

   
作者: xiaochuanjiejie    时间: 2013-03-07 11:13
cao627 发表于 2013-03-06 21:09
回复 22# xiaochuanjiejie


明白了,非常感谢你的耐心讲解。
谢谢!不知**可以打10分的地方,真想给你个10分挂你号上,哈哈!!
作者: wzb56    时间: 2014-01-01 12:09
牛呗,学习了!!!




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