我有 2 个大的 csv 文件,file1.csv 看起来像这样
1,2,3,4
1,4,5,6
1,7,8,9
1,11,13,17
file2.csv 看起来像这样
1,2,3,4
1,7,8,9
2,4,9,10
13,14,17,18
这些只是我编造的随机数,基本上是两个相同且已排序的数字。我想比较 file1.csv 和 file2.csv,然后将 file1.csv 中存在但不在 file2.csv 中的行复制到 file3.csv。分隔符显然是逗号
我试过
comm -2 -3 file.csv file2.csv > file3.csv
我试过了
diff -u file.csv file2.csv >> file3.csv
两种方法都不起作用,因为 file3 比 file1 和 file2 都大。我尝试了不同的diff
andcomm
命令,有时它比 file2 大,与文件 file1 大小差不多,我知道 file3 的大小必须比 file1 和 file2 小得多。当然,我查看了 file3,但结果不是我想要的
此时,我知道可以用diff
或来完成comm
,但我不知道要使用什么命令。
答案1
尝试这个命令:
grep -v -f file2.csv file1.csv > file3.csv
根据grep 手册:
-f FILE, --file=FILE
Obtain patterns from FILE, one per line. The empty file
contains zero patterns, and therefore matches nothing. (-f is
specified by POSIX.)
-v, --invert-match
Invert the sense of matching, to select non-matching lines. (-v
is specified by POSIX.)
正如 Steeldriver 在他的评论中所说,最好还添加-x
以下-F
内容:
-F, --fixed-strings
Interpret PATTERN as a list of fixed strings, separated by
newlines, any of which is to be matched. (-F is specified by
POSIX.)
-x, --line-regexp
Select only those matches that exactly match the whole line.
(-x is specified by POSIX.)
因此,更好的命令是:
grep -xvFf file2.csv file1.csv > file3.csv
该命令使用file2.csv
行作为模式并打印file1.csv
不匹配的行(-v
)。
答案2
为了能够使用comm
,您必须先对行进行排序。
comm -23 <(sort file1.csv) <(sort file2.csv) > file3.csv
答案3
一个 Python 选项:
#!/usr/bin/env python3
import sys
def readfile(file):
with open(file) as src:
return [line.strip() for line in src.readlines()]
lines_1 = readfile(sys.argv[1]); lines_2 = readfile(sys.argv[2])
for line in lines_1:
if not line in lines_2:
print(line)
输出:
1,4,5,6
1,11,13,17
将脚本粘贴到空文件中extract.py
,使其可执行并通过以下命令运行它:
<script> <file_1> <file_2>
或者直接写入file_3:
<script> <file_1> <file_2> >file_3
答案4
使用diff
命令执行grep
,无需存储。
如果文件 1 中存在行,但文件 2 中不存在行,则输出:
$ diff file{1,2}.csv | grep -Po "^< \K.*"
1,4,5,6
1,11,13,17
如果文件 2 中存在行,而文件 1 中不存在行,则输出此信息,只需将左角 ( <
) 更改为右角 ( >
):
$ diff file{1,2}.csv | grep -Po "^> \K.*"
2,4,9,10
13,14,17,18