当前位置:  开发笔记 > 编程语言 > 正文

Unix命令查找两个文件中常见的行

如何解决《Unix命令查找两个文件中常见的行》经验,为你挑选了8个好方法。

我确定我曾经发现一个unix命令可以打印两个或多个文件中的公共行,有人知道它的名字吗?这比简单得多diff.



1> Jonathan Lef..:

你正在寻找的命令是comm.例如:-

comm -12 1.sorted.txt 2.sorted.txt

这里:

-1:禁止第1列(1.sorted.txt唯一的行)

-2:抑制第2列(2.sorted.txt唯一的行)


虽然comm需要排序文件,但您可以使用grep -f file1 file2来获取两个文件的公共行.
典型用法:comm -12 1.sorted.txt 2.sorted.txt
请参阅下面的[ferdy](http://stackoverflow.com/users/61903/ferdy)的[答案](http://stackoverflow.com/a/28051421/15168)和[Christopher Schultz](http:/ /stackoverflow.com/users/276232/christopher-schultz)和我的评论.TL; DR - 使用`grep -F -x -f file1 file2`.
@ferdy(从你的回答中重复我的评论,因为你的评论基本上是作为评论发布的重复答案)`grep`做了一些你可能没想到的奇怪的事情.具体来说,`1.txt`中的所有内容都将被解释为正则表达式而不是纯字符串.此外,`1.txt`中的任何空行都将匹配`2.txt`中的所有行.所以`grep`只能在非常特殊的情况下工作.你至少想要使用`fgrep`(或`grep -f`),但空白行可能会对这个过程造成严重破坏.

2> Stephan Wehn..:

要轻松将comm命令应用于未排序的文件,请使用Bash的进程替换:

$ bash --version
GNU bash, version 3.2.51(1)-release
Copyright (C) 2007 Free Software Foundation, Inc.
$ cat > abc
123
567
132
$ cat > def
132
777
321

所以文件abc和def有一条共同的行,一行是"132".在未排序的文件上使用comm:

$ comm abc def
123
    132
567
132
    777
    321
$ comm -12 abc def # No output! The common line is not found
$

最后一行没有产生输出,没有发现公共线.

现在使用comm对已排序的文件,使用进程替换对文件进行排序:

$ comm <( sort abc ) <( sort def )
123
            132
    321
567
    777
$ comm -12 <( sort abc ) <( sort def )
132

现在我们得到了132线!


所以...`sort abc> abc.sorted`,`sort dev> def.sorted`然后`comm -12 abc.sorted def.sorted`?

3> Tatjana Heus..:

为了补充Perl单线程,这是它的awk等价物:

awk 'NR==FNR{arr[$0];next} $0 in arr' file1 file2

这将读取所有行file1到数组中arr[],然后检查每一行file2是否已存在于数组中(即file1).找到的行将按其出现的顺序打印file2.请注意,比较in arr使用从file2索引到数组的整行,因此它只会在整行上报告完全匹配.


这(!)是正确的答案.没有其他人可以普遍工作(我没有尝试过`perl`,因为).万分感谢女士

4> Johannes Sch..:

也许你的意思comm

逐行比较已排序的文件FILE1和FILE2.

没有选项,产生三列输出.第一列包含FILE1特有的行,第二列包含FILE2特有的行,第三列包含两个文件共有的行.

查找这些信息的秘诀是信息页面.对于GNU程序,它们比人工页面更详细.尝试info coreutils它会列出所有小的有用的工具.



5> ferdy..:

grep -v -f 1.txt 2.txt > 3.txt

给你两个文件的差异(2.txt中的内容,而不是1.txt中的内容),你可以很容易地做到

grep -f 1.txt 2.txt > 3.txt

收集所有常见的行,这应该为您的问题提供简单的解决方案.如果你有文件,你应该采取comm.问候!


@ChristopherSchultz:有可能使用POSIX [`grep`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html)符号来升级这个答案,这些符号由`grep`支持在大多数现代Unix变种上找到.添加`-F`(或使用`fgrep`)来抑制正则表达式.添加`-x`(精确)以仅匹配整行.
`grep`做了一些你可能没想到的奇怪的事情.具体来说,`1.txt`中的所有内容都将被解释为正则表达式而不是纯字符串.此外,`1.txt`中的任何空行都将匹配`2.txt`中的所有行.所以这只适用于非常具体的情况.
@UlysseBN`com.com`可以处理任意大的文件,只要它们被排序,因为它只需要在内存中保存三行(我猜GNU`com`甚至知道只保留一个前缀,如果这些行是真的长).`grep`解决方案需要将所有搜索表达式保留在内存中.

6> 小智..:
perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/'  file1 file2



7> Basj..:

如果这两个文件尚未排序,则可以使用:

comm -12 <(sort a.txt) <(sort b.txt)

它将起作用,避免comm: file 2 is not in sorted order 这样做时出现错误消息comm -12 a.txt b.txt



8> 小智..:
awk 'NR==FNR{a[$1]++;next} a[$1] ' file1 file2

推荐阅读
夏晶阳--艺术
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有