有没有一个简单快速的解决方案来比较bash中的两个csv文件?

有没有一个简单快速的解决方案来比较bash中的两个csv文件?,bash,csv,file,grep,diff,Bash,Csv,File,Grep,Diff,我的问题是: 我有两个大的csv文件,有数百万行 one文件包含来自我的服务器的数据库备份,看起来像: securityCode,isScanned NALEJNSIDO,false NALSKIFKEA,false NAPOIDFNLE,true ... 现在我有了另一个CSV文件,其中包含新的代码,如,具有完全相同的模式 我想比较这两个,只找到服务器上还没有的代码。因为我的一个朋友会生成随机代码,所以我们希望确保只更新服务器上尚未更新的代码 我试着用sort-u serverBackup.

我的问题是: 我有两个大的csv文件,有数百万行

one文件包含来自我的服务器的数据库备份,看起来像:

securityCode,isScanned
NALEJNSIDO,false
NALSKIFKEA,false
NAPOIDFNLE,true
...
现在我有了另一个CSV文件,其中包含新的代码,如,具有完全相同的模式

我想比较这两个,只找到服务器上还没有的代码。因为我的一个朋友会生成随机代码,所以我们希望确保只更新服务器上尚未更新的代码

我试着用
sort-u serverBackup.csv>serverBackupSorted.csv
sort-u newCodes.csv>newcodesorted.csv对它们进行排序

split -a 4  --lines 10000 serverBackup.csv splitted
cp newCodes.csv newCodes.csv.org
for f in splitted*; do
   grep -vFxf "${f}" newCodes.csv > smaller
   mv smaller newCodes.csv
done
rm splitted*
首先,我尝试使用
grep-F-x-F newcodesorted.csv服务器backupsorted.csv
,但由于占用了太多资源,进程被终止,因此我认为必须有更好的方法

然后我使用diff仅在newcodesorted.csv中查找新行,如
diff-serverBackupSorted.csv newcodesorted.csv

我相信您可以直接告诉diff,您只想要与第二个文件的差异,但我不明白如何进行,因此我将输入变灰,知道我稍后会剪切/删除不需要的字符:
diff serverBackupSorted.csv newcodestorted.csv | grep'>'>greppedCodes

但我相信一定有更好的办法

所以我问你,如果你有任何想法,如何改进这个方法

编辑:

通信到目前为止效果很好。但有一件事我忘了提到,服务器上的一些代码已经被扫描过了

但是新代码总是用ISSConned=false初始化。所以newCodes.csv看起来像

securityCode,isScanned
ALBSIBFOEA,false
OUVOENJBSD,false
NAPOIDFNLE,false
NALEJNSIDO,false
NPIAEBNSIE,false
...
我不知道使用cut-d','-f1将其简化为代码和使用comm是否足够


我试过了,一次用grep,一次用comms得到了不同的结果。所以我有点不确定,哪一个是正确的方法^^

是的!一个被高度低估的工具
comm
非常适合这一点。 偷来的例子


如果这是一个您将来可能经常使用的命令,那么这可能很方便。

我认为对文件进行排序会占用大量资源。
当您只需要新行时,可以使用选项
-v
grep

grep -vFxf serverBackup.csv newCodes.csv 
或第一次拆分
serverBackup.csv

split -a 4  --lines 10000 serverBackup.csv splitted
cp newCodes.csv newCodes.csv.org
for f in splitted*; do
   grep -vFxf "${f}" newCodes.csv > smaller
   mv smaller newCodes.csv
done
rm splitted*
鉴于:

您可以使用awk:

$ awk 'FNR==NR{seen[$0]; next} !($0 in seen)' f1 f2
NALSKIFKEA,true
NAPOIDFNLE,false
SOMETHINGELSE,true

请发布其他csv文件的一些示例以进行测试和预期输出。将它们添加到您的问题中,不要将它们作为评论或图片发布。谢谢。您是否只关心检查代码为
,false
的新文件?正确的方法是使用
awk
。否则,您最终会对每个百万行文件进行多次传递。换言之,您是否希望跳过已扫描的其他文件中的常用名称
,true
?+1以提及
comm
,但应指出输入文件需要事先排序;也许再加上一个例子:
comm-12@markp fuso,这是一个很好的观点。我没有提到它,因为原来的海报已经对文件进行了排序,但最好是明确的。我已经添加了您的示例。请注意,这里的答案并不局限于bash,据我所知,至少应该在zsh和ksh下工作。@Roadowl好极了,它在fish下对我有效。
split -a 4  --lines 10000 serverBackup.csv splitted
cp newCodes.csv newCodes.csv.org
for f in splitted*; do
   grep -vFxf "${f}" newCodes.csv > smaller
   mv smaller newCodes.csv
done
rm splitted*
$ cat f1
securityCode,isScanned
NALEJNSIDO,false
NALSKIFKEA,false
NAPOIDFNLE,true

$ cat f2
securityCode,isScanned
NALEJNSIDO,false
NALSKIFKEA,true
NAPOIDFNLE,false
SOMETHINGELSE,true
$ awk 'FNR==NR{seen[$0]; next} !($0 in seen)' f1 f2
NALSKIFKEA,true
NAPOIDFNLE,false
SOMETHINGELSE,true