我想将file1与file2进行比较,并生成一个file3,其中包含file1中不存在于file2中的行。
答案 0 :(得分:194)
diff(1)不是答案,但是comm(1)是。
NAME
comm - compare two sorted files line by line
SYNOPSIS
comm [OPTION]... FILE1 FILE2
...
-1 suppress lines unique to FILE1
-2 suppress lines unique to FILE2
-3 suppress lines that appear in both files
所以
comm -2 -3 file1 file2 > file3
必须对输入文件进行排序。如果不是,请先排序。这可以使用临时文件来完成,或者......
comm -2 -3 <(sort file1) <(sort file2) > file3
前提是你的shell支持进程替换(bash)。
答案 1 :(得分:44)
Unix实用程序diff
就是为了这个目的。
$ diff -u file1 file2 > file3
有关选项,不同输出格式等,请参阅手册和Internet。
答案 2 :(得分:20)
考虑一下:
文件a.txt:
abcd
efgh
文件b.txt:
abcd
您可以通过以下方式找到差异:
diff -a --suppress-common-lines -y a.txt b.txt
输出将是:
efgh
您可以使用以下命令在输出文件(c.txt)中重新映射输出:
diff -a --suppress-common-lines -y a.txt b.txt > c.txt
这将回答你的问题:
&#34; ...包含file1中的行 不存在于file2中。&#34;
答案 3 :(得分:7)
有时diff
是您需要的实用程序,但有时候join
更合适。这些文件需要预先排序,或者如果你使用的是支持进程替换的shell,比如bash,ksh或zsh,你可以动态地进行排序。
join -v 1 <(sort file1) <(sort file2)
答案 4 :(得分:5)
尝试
sdiff file1 file2
在大多数情况下,对我来说通常效果更好。 如果行的顺序不重要(例如某些文本配置文件),您可能希望先排序文件。
例如,
sdiff -w 185 file1.cfg file2.cfg
答案 5 :(得分:3)
如果你需要使用coreutils来解决这个问题,那么接受的答案是好的:
comm -23 <(sort file1) <(sort file2) > file3
您还可以使用sd(流差异),它不需要排序或处理替换并支持无限流,如下所示:
cat file1 | sd 'cat file2' > file3
在这个例子中可能没有那么多的好处,但仍然考虑它;在某些情况下,您将无法使用comm
,grep -F
或diff
。
这是我写的关于在终端上传播流的blogpost,它引入了sd。
答案 6 :(得分:2)
已经有很多答案,但没有一个完美恕我直言。 Thanatos的回答每行留下一些额外的字符,而Sorpigal的回答要求对文件进行排序或预先排序,这在所有情况下可能都不够。
我认为获得不同的线条的最好方法是没有其他(没有额外的字符,没有重新排序)是diff
,grep
和awk
的组合(或类似的)。
如果这些行不包含任何“&lt;”,则短单行可以是:
diff urls.txt* | grep "<" | sed 's/< //g'
但是这将从行中删除“&lt;”(小于空格)的每个实例,这并不总是正常的(例如源代码)。最安全的选择是使用awk:
diff urls.txt* | grep "<" | awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}'
这个单行文件对两个文件进行区分,然后过滤出diff的ed样式输出,然后删除尾随的“&lt;”差异增加了。即使行包含一些“&lt;”,这也可以工作他们自己。
答案 7 :(得分:1)
使用Diff实用程序并仅提取以&lt;开头的行。在输出中
答案 8 :(得分:1)
diff a1.txt a2.txt | grep '> ' | sed 's/> //' > a3.txt
我在这个帖子中尝试了几乎所有的答案,但都没有完成。经过几条路径,一条路为我工作。 差异会给你带来不同但有一些不必要的特殊字符。实际差异线以&#39;&gt;开头的地方&#39 ;.所以下一步是 grep 行以&#39;&gt;开头&#39;然后使用 sed 删除相同内容。
答案 9 :(得分:0)
还没有grep
解决方案吗?
行:
grep -Fxvf file1 file2 > file3
行:
grep -Fxvf file2 file1 > file3
行:
grep -Fxf file1 file2 > file3
答案 10 :(得分:0)
您可以将diff
用于以下输出格式:
diff --old-line-format='' --unchanged-line-format='' file1 file2
--old-line-format=''
,如果file2中的行不同,则禁用file1的输出。
--unchanged-line-format=''
,如果行相同则禁用输出。
答案 11 :(得分:0)
我很惊讶没有人提到diff -y
来产生并排输出,例如:
diff -y file1 file2 > file3
在file3
中(不同的行中间有符号|
)
same same
diff_1 | diff_2
答案 12 :(得分:0)
如果您的CSV文件具有单列甚至多列,则可以使用sqlite3嵌入式数据库逐行执行“ diff”操作。它带有python,因此应该在大多数linux / macs上可用。您可以在bash shell上编写sqlite3命令的脚本,而无需编写python。
echo "
.mode csv
.import a.csv atable
.import b.csv btable
create table result as select * from atable EXCEPT select * from btable;
.output result.csv
select * from result ;
.quit
" | sqlite3 temp.db
注意:确保每个sqlite3命令都有一个换行符。
工作原理
如果需要对特定列进行操作,则可以使用sqlite3或任何数据库。
我尝试使用内置的diff和comm工具对多个GB文件进行比较。 Sqlite击败了Linux实用程序。