为了账号安全,请及时绑定邮箱和手机立即绑定

基于每行中的第一个令牌比较2个大文件的最佳方法是什么?

基于每行中的第一个令牌比较2个大文件的最佳方法是什么?

慕斯709654 2022-09-01 17:32:41
我有2个大文件(每个大约500k行或85mb),包含文件的校验和和文件路径本身。根据校验和获取文件之间差异的最佳方法是什么?我可以编写Java程序,脚本等,但目标是它必须高效。例如,我有FileA:ec7a063d3990cf7d8481952ffb45f1d8b490b1b5  /home/user/first.txt e0f886f2124804b87a81defdc38ad2b492458f34  /home/user/second.txt文件 B:650bc1eb1b24604819eb342f2ebc1bab464d9210  /home/user/third.txt ec7a063d3990cf7d8481952ffb45f1d8b490b1b5  /home/user/blah/dup.txt我想输出两个文件,其中包含文件A和B中的唯一文件。独一无二e0f886f2124804b87a81defdc38ad2b492458f34  /home/user/second.txt独特B650bc1eb1b24604819eb342f2ebc1bab464d9210  /home/user/third.txt在这种情况下,“first.txt”和“dup.txt”是相同的,因为它们的校验和是相同的,所以我将其排除为不唯一。最有效的方法是什么?文件不会以任何方式排序。
查看完整描述

3 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

所以这里有一个快速的答案,但它不是那么有效:


$ join -v1 <(sort FileA) <(sort FileB) | tee UniqueA

e0f886f2124804b87a81defdc38ad2b492458f34 /home/user/second.txt


$ join -v2 <(sort FileA) <(sort FileB) | tee UniqueB

650bc1eb1b24604819eb342f2ebc1bab464d9210 /home/user/third.txt

join 命令按键匹配两个已排序文件中的行(默认情况下,键是具有默认空间定界符的第一个字段)。但是,上面的命令效率不高,因为我们对文件进行了两次排序:一次是获取第一个文件 (-v1) 的唯一值,另一次是获取第二个文件 (-v2) 的唯一值。我很快就会发布一些改进。


您可以在单个调用中获取唯一的值,但原始文件会丢失。请参阅下面的代码:


$ join -v1 -v2 <(sort FileA) <(sort FileB)

650bc1eb1b24604819eb342f2ebc1bab464d9210 /home/user/third.txt

e0f886f2124804b87a81defdc38ad2b492458f34 /home/user/second.txt

在这一点上,我们几乎有了答案。我们拥有两个文件中所有不匹配的文件。此外,我们只对每个文件进行了一次排序。我相信这是有效的。但是,您丢失了“原点”信息。我们可以使用此迭代或代码用 sed 标记行:


$ join -v1 -v2 <(sort FileA | sed s/$/\ A/ ) <(sort FileB | sed s/$/\ B/ )

650bc1eb1b24604819eb342f2ebc1bab464d9210 /home/user/third.txt B

e0f886f2124804b87a81defdc38ad2b492458f34 /home/user/second.txt A

此时,我们有唯一的条目,我们知道它们来自哪个文件。如果您必须在单独的文件中获得结果,我想您可以使用awk(或只是更多的bash)来完成此操作。下面是包含 awk 的代码的又一次迭代:


join -v1 -v2 <(sort FileA | sed s/$/\ A/ ) <(sort FileB | sed s/$/\ B/ ) |  awk '{ file="Unique" $3 ; print $1,$2 > file }


查看完整回答
反对 回复 2022-09-01
?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

一个只有bash的解决方案:


# create a file with a mark that help to find the source of the hash remove duplicate 

sed 's/^\([0-9a-f]*\)[^0-9a-f]/\1=A=/' FileA | sort | uniq -w 32 > FileA.mark

sed 's/^\([0-9a-f]*\)[^0-9a-f]/\1=B=/' FileB | sort | uniq -w 32 > FileB.mark


# sort the 2 files together , keep only unique hashs 

sort -t= FileA.mark FileB.mark | uniq -w 32 -c  >  HashCountFromAB


# if the count equal 1 ( provide by option -c from uniq )

# we use the mark to find the origin of the hash 


grep '^ *1 [0-9a-f]*=A=' HashCountFromAB > FileA.uniq

grep '^ *1 [0-9a-f]*=B=' HashCountFromAB > FileB.uniq


查看完整回答
反对 回复 2022-09-01
?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

对每个文件进行排序,然后将结果与 进行比较。这两个命令的用法在同名手册页中进行了说明。sortcomm



查看完整回答
反对 回复 2022-09-01
  • 3 回答
  • 0 关注
  • 134 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号