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

我确信我曾经find一个可以从两个或多个文件中打印通用命令的unix命令,有人知道它的名字吗? 这比diff更简单。

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

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

这里:

-1 :压制第1列(1.sorted.txt唯一的行)

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

要轻松地将comm命令应用于未sorting的文件,请使用Bash的进程replace :

 $ 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”。 在未sorting的文件上使用comm

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

最后一行没有输出,没有发现通用行。

现在在sorting的文件中使用comm ,使用进程replace对文件进行sorting:

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

现在我们得到了132线!

也许你是指comm

逐行比较sorting文件FILE1和FILE2。

没有select,产生三列输出。 第一列包含对FILE1唯一的行,第二列包含对FILE2唯一的行,第三列包含两个文件共有的行。

find这些信息的秘诀是信息页面。 对于GNU程序,它们比他们的手册要详细得多。 尝试info coreutils ,它会列出你所有的小有用的使用情况。

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

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

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

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

给你两个文件的差异(2.txt中的而不是1.txt中的),你可以轻松地做一个

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

收集所有常见的线路,这应该为您的问题提供一个简单的解决scheme。 如果你有sorting的文件,你应该接受comm 。 问候!

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

在有限版本的Linux上(例如QNAP(nas))我正在研究:
– 通信不存在
grep -f file1 file2可能会引起一些问题,如@ChristopherSchultz所说,使用grep -F -f file1 file2真的很慢(超过5分钟 – 没有完成 – 超过20MB的文件超过2-3秒,下面的方法)

所以这就是我所做的:

 sort file1 > file1.sorted sort file2 > file2.sorted diff file1.sorted file2.sorted | grep "<" | sed 's/^< *//' > files.diff diff file1.sorted files.diff | grep "<" | sed 's/^< *//' > files.same.sorted 

如果“files.same.sorted”的顺序与原来的顺序相同,那么添加此行的顺序与file1相同:

awk 'FNR==NR {a[$0]=$0; next}; $0 in a {print a[$0]}' files.same.sorted file1 > files.same

或者,对于与file2相同的顺序:

awk 'FNR==NR {a[$0]=$0; next}; $0 in a {print a[$0]}' files.same.sorted file2 > files.same

 awk 'NR==FNR{a[$1]++;next} a[$1] ' file1 file2 

仅供参考,如果有人仍在关注如何为多个文件执行此操作,请参阅链接的答案以在多个文件中查找匹配行。


结合这两个答案( ans1和ans2 ),我认为你可以得到你需要的结果,而不需要sorting文件:

 #!/bin/bash ans="matching_lines" for file1 in * do for file2 in * do if [ "$file1" != "$ans" ] && [ "$file2" != "$ans" ] && [ "$file1" != "$file2" ] ; then echo "Comparing: $file1 $file2 ..." >> $ans perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/' $file1 $file2 >> $ans fi done done 

只需保存它,赋予它执行权限( chmod +x compareFiles.sh )并运行它。 它将获取当前工作目录中的所有文件,并将“全部”与“全部”比较结果留在“matching_lines”文件中。

需要改进的地方:

  • 跳过目录
  • 避免比较所有文件两次(file1 vs file2和file2 vs file1)。
  • 也许在匹配的string旁边添加行号

如果这两个文件还没有sorting,您可以使用:

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

它将工作,避免错误消息comm: file 2 is not in sorted ordercomm -12 a.txt b.txt

 rm file3.txt cat file1.out | while read line1 do cat file2.out | while read line2 do if [[ $line1 == $line2 ]]; then echo $line1 >>file3.out fi done done 

这应该做到这一点。