Lyn*_*nob 6 command-line bash csv text-processing
我有 2 个大 csv 文件,file1.csv,看起来像这样
1,2,3,4
1,4,5,6
1,7,8,9
1,11,13,17
Run Code Online (Sandbox Code Playgroud)
file2.csv 看起来像这样
1,2,3,4
1,7,8,9
2,4,9,10
13,14,17,18
Run Code Online (Sandbox Code Playgroud)
这些只是我编造的随机数,基本上是相同和排序的两个数字。我想比较file1.csv 和file2.csv,然后将file1.csv 中存在但file2.csv 中不存在的行复制到file3.csv。分隔符显然是逗号
我试过
comm -2 -3 file.csv file2.csv > file3.csv
Run Code Online (Sandbox Code Playgroud)
我试过
diff -u file.csv file2.csv >> file3.csv
Run Code Online (Sandbox Code Playgroud)
两者都不起作用,因为 file3 比 file1 和 file2 大。我尝试了不同的diff
和comm
命令,有时它是比file2更大,差不多大小的文件文件1,我知道,文件3在尺寸上比file1和file2的是显著少。当然我看的是file3,而不是我想要的结果
在这一点上,我知道可以使用diff
orcomm
但我不知道要使用的命令。
试试这个命令:
grep -v -f file2.csv file1.csv > file3.csv
Run Code Online (Sandbox Code Playgroud)
根据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.)
Run Code Online (Sandbox Code Playgroud)
正如 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.)
Run Code Online (Sandbox Code Playgroud)
所以,更好的命令是:
grep -xvFf file2.csv file1.csv > file3.csv
Run Code Online (Sandbox Code Playgroud)
此命令使用file2.csv
line 作为模式并打印file1.csv
不匹配的行 ( -v
)。
为了能够使用comm
,您必须先对行进行排序。
comm -23 <(sort file1.csv) <(sort file2.csv) > file3.csv
Run Code Online (Sandbox Code Playgroud)