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 order
做comm -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
这应该做到这一点。