V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
Martin9
V2EX  ›  Linux

linux 如何根据多列去重

  •  
  •   Martin9 · 2016-12-26 14:00:41 +08:00 · 5394 次点击
    这是一个创建于 2699 天前的主题,其中的信息可能已经有所发展或是发生改变。

    采用 awk '!x[$0]++' filename 只能去除完全相同的重复值, awk '!x[$1]++' filename 只能根据第一列的值去重。

    现在想要根据多列的数据去重,何解?

    (不能借助数据库,或者还有其他的命令能解决?

    第 1 条附言  ·  2016-12-26 18:44:04 +08:00
    问题已解决,基本采用 @swulling 的方法。由于源文件分隔符是"|", 所以指令是
    awk -F '|' '!x[$1 ,$3]++' filename > filename_dedup

    回复已感谢。
    12 条回复    2016-12-26 18:47:47 +08:00
    knightdf
        1
    knightdf  
       2016-12-26 15:03:36 +08:00   ❤️ 1
    把这几列拼成字符串再去重不就行了?
    imn1
        2
    imn1  
       2016-12-26 15:08:13 +08:00   ❤️ 1
    csvtool 辅助
    Martin9
        3
    Martin9  
    OP
       2016-12-26 15:49:06 +08:00
    @knightdf 那还有其他列的数据要搞,而且这个列位置不能变的
    swulling
        4
    swulling  
       2016-12-26 15:51:39 +08:00
    awk '!x[$0","$1","$3]++',思路要广
    Martin9
        5
    Martin9  
    OP
       2016-12-26 16:07:57 +08:00
    @imn1 服务器端能用么
    Martin9
        6
    Martin9  
    OP
       2016-12-26 16:10:01 +08:00
    @swulling 这个是根据第一列和第三列去重么?
    我之前用过 awk '!x[$1,$3]++' 去重后条数对不上
    imn1
        7
    imn1  
       2016-12-26 16:16:54 +08:00
    @Martin9
    csvtool 是命令行,不过它还是要和其他命令结合用,本身并不算强大

    其实处理多列文本如 csv ,还没有什么强大的 cli 工具,我更多用自写 python 处理
    swulling
        8
    swulling  
       2016-12-26 16:53:36 +08:00   ❤️ 1
    @Martin9 是 $1","$3 ,不是 $1,$3 ,前者是拼接
    xss
        9
    xss  
       2016-12-26 17:04:26 +08:00   ❤️ 1
    step 0 : 将要去重的列拼接成一个字符串然后算一个 hash(以 md5 为例, 只要保证位数固定就行)得到列 A
    step 1 : 将列 A 当做第一列, 原始日志当做剩余的列输出
    step 2 : uniq 有一个参数
    -w, --check-chars=N 对每行第 N 个字符以后的内容不作对照

    所以, uniq -w32 列 A 为第一列的日志.log

    即可完成多列去重.

    例子命令(a.log 中, 根据第一列和第三列去重):
    ```
    user@host [16:58:30] : ~
    >> cat a.log | awk '{cmd="echo -ne " $1$3"|md5sum -";cmd|getline result;print result"\t"$0}'|sort|uniq -w32 -c
    1 7b19de6d4d54999531beb27f758f71f6 - 111 222 333 444
    1 c17ed7d7e2d8a60c78c715e165fe3c38 - 111 888 444 666
    2 ec1e7077d02cb3dbd61ab73018c4a319 - 111 666 333 777
    user@host [16:58:49] : ~
    >> cat a.log
    111 222 333 444
    222 333 444 555
    111 666 333 777
    111 888 444 666
    ```
    knightdf
        10
    knightdf  
       2016-12-26 18:19:14 +08:00
    @Martin9 大哥,你知道联合主键这个词么?
    Martin9
        11
    Martin9  
    OP
       2016-12-26 18:37:49 +08:00
    @knightdf 恩这两列在数据库是联合主键,所以 load 到数据库前要去重
    Ginson
        12
    Ginson  
       2016-12-26 18:47:47 +08:00
    好不容易看到个我能答的,被抢先了,哭…
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   947 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:10 · PVG 04:10 · LAX 13:10 · JFK 16:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.