V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Tinet
V2EX  ›  问与答

请教linux下面的一个命令,或者命令组合?

  •  
  •   Tinet · 2013-03-15 15:58:12 +08:00 · 2996 次点击
    这是一个创建于 4275 天前的主题,其中的信息可能已经有所发展或是发生改变。
    这两天在工作的时候遇到这样一个问题:
    两个文本文件,数据是一行一行放的,我想查看文件A中哪些行是文件B中没有的,自己也找了一些,感觉达不到目的,总觉得那些程序是按两个文件中相同的行在比较(具体不清楚,求指教)但是我要的效果是把文件A中的一行挨个去和B中的每一行进行比较,看有没有相同的,直到把A中的所有行比较完,最后输出A中那些在B中不存在的行。
    不知道我的问题有没有描述清楚,大家给我点建议吧,你们在遇到这种问题的时候是怎么解决的?
    7 条回复    1970-01-01 08:00:00 +08:00
    yangg
        1
    yangg  
       2013-03-15 16:20:06 +08:00
    如果没顺序就是
    cat a.txt | while read line; do grep "$line" b.txt > /dev/null || echo $line; done

    有顺序的话直接diff吧
    yangg
        2
    yangg  
       2013-03-15 16:22:57 +08:00   ❤️ 1
    修正下,整行相同,而不是匹配

    cat a.txt | while read line; do grep "^$line$" b.txt > /dev/null || echo $line; done
    Tinet
        3
    Tinet  
    OP
       2013-03-15 16:36:10 +08:00
    @yangg 如果不想区分大小写呢
    clww
        4
    clww  
       2013-03-15 16:40:15 +08:00
    @Tinet grep加-i开关
    Tinet
        5
    Tinet  
    OP
       2013-03-15 16:49:13 +08:00
    @yangg 我试了一下,A中和B相同的行也被输出了,有点问题
    swulling
        6
    swulling  
       2013-03-15 16:55:58 +08:00   ❤️ 1
    需求:找出文件a中哪些行是文件b中没有的

    方案1:
    @yangg 的方法,没有对grep做任何参数限制,几千行对比就会很慢了。。而且为啥一长串?
    正确方法是 cat a | grep -vFf b
    如果不区分大小写,加-i参数即可

    方案2:
    如果数据量到达1000w以上,你会发现grep会把内存打满,无法使用
    用awk即可

    输出a和b的相同行
    awk 'ARGIND==1{a[$0]} ARGIND>1&&($0 in a){print $0}' a b > same.out

    输出文件a中哪些行是文件b中没有的
    awk 'ARGIND==1{a[$0]} ARGIND>1&&!($0 in a){print $0}' a b > a-b.out
    swulling
        7
    swulling  
       2013-03-15 16:59:22 +08:00
    P.S awk内存占用约等于文件a的行数*awk内置hash长度(64bit=8Byte?记不太清楚了)

    性能大约是1000w的a和1000w的b对比,几分钟,而且时间和内存占用是和行数线性相关的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3264 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 12:28 · PVG 20:28 · LAX 04:28 · JFK 07:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.