我有“test1.csv”,它包含
200,400,600,800
100,300,500,700
50,25,125,310
和 test2.csv 它包含
100,4,2,1,7
200,400,600,800
21,22,23,24,25
50,25,125,310
50,25,700,5
现在
diff test2.csv test1.csv > result.csv
不同于
diff test1.csv test2.csv > result.csv
我不知道哪个是正确的顺序,但我想要别的东西,上面的两个命令都会输出类似
2 > 100,4,2,1,7
3 2,3c3,5
4 < 100,300,500,700
5 < 50,25,125,310
6 \ No newline at end of file
7 ---
8 > 21,22,23,24,25
9 > 50,25,125,310
我只想输出差异,因此 results.csv 应该是这样的
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
我试过了diff -q
,diff -s
但他们没有成功。顺序无关紧要,重要的是我只想看到差异,没有 > 也没有 < 也没有空格。
grep -FvF
在小文件而不是大文件上做了技巧
第一个文件包含超过 500 万行,第二个文件包含 1300 行。
所以 results.csv 应该产生 ~4,998,700 行
我也试过grep -F -x -v -f
没有用。
听起来像是一份工作
comm
:如中所述
man comm
:因此,这
-3
意味着只会打印其中一个文件独有的行。然而,这些是根据它们所在的文件缩进的。要删除选项卡,请使用:在这种情况下,你甚至不需要对文件进行排序,你可以将上面的内容简化为:
grep
与bash
进程替换一起使用:将输出保存为
results.csv
:<()
是bash
进程替换模式grep -vFf test2.csv test1.csv
会发现唯一的行test1.csv
grep -vFf test1.csv test2.csv
会发现唯一的行test2.csv
最后,我们通过以下方式总结结果
cat
或者按照Oli 的建议,您也可以使用命令分组:
或者只是一个接一个地运行,因为它们都在写入 STDOUT,它们最终会被添加:
如果行的顺序不相关,请使用
awk
orperl
:用于
grep
获取公共线路并将其过滤掉:内部 grep 获取公共行,然后外部 grep 查找与这些公共行不匹配的行。
使用
--*-line-format=...
选项diff
你可以
diff
准确地说出你需要什么 - 解释如下:可以非常详细地指定 diff 的输出,类似于
printf
数字格式。第一个文件中的行
test1.csv
称为“旧”行,第二个文件中的行称为test2.csv
“新”行。diff
当用于查看文件中更改的内容时,这是有意义的。我们需要的选项是为“旧”行、“新”行和“未更改”行设置格式的选项。
我们需要的格式非常简单:
对于变化的行,新的和旧的,我们只想输出行的文本。
%L
是行文本的格式符号。对于未更改的行,我们不想显示任何内容。
有了这个,我们可以使用您的示例数据编写诸如 之类
--old-line-format='%L'
的选项并将它们放在一起:性能说明
由于文件大小不同,如果没有关系,请尝试交换输入文件,这可能是 的内部工作
diff
方式可以比另一种方式更好地处理。更好的是需要更少的内存或更少的计算。有一个用于
diff
大文件的优化选项:--speed-large-files
. 它使用关于文件结构的假设,因此不清楚它是否对您的情况有帮助,但值得一试。格式选项在下面
man diff
描述--LTYPE-line-format=LFMT
。由于不需要保留订单,只需:
sort test1.csv test2.csv
:合并和排序test1.csv
和test2.csv
uniq -u
: 只打印没有重复的行