0 0

关于比较两个超大文件的差异,有什么好的思路30

有两个文件A和B,分别保存了一个系统两天的数据快照。
a.txt
(格式为:号码,姓名,年龄,姓别,状态)
13900001111,小A,20,男,01
13900001112,小H,20,女,06
13900001113,小C,20,男,06
13900001114,小D,20,男,04
13900001116,小E,20,女,04
13900001118,小F,20,男,04
13900001119,小G,20,女,07

b.txt
(格式和a一样:号码,姓名,年龄,姓别,状态)
13900001111,小A,20,男,01
13900001113,小C,20,男,06
13900001114,小D,20,男,04
13900001116,小E,20,女,04
13900001118,小F,20,男,04
13900001119,小G,20,女,01
13900001120,小K,23,女,01

b文件比a多了一个“小K”,但是少了一个“小H”,另外“小G”的状态被改为“01”,两个文件的号码都是唯一标识。
我想达到的目的是
1、想快速的在B文件中找出对比A少的记录和多出来的记录。
2、找出B文件中状态被修改的记录
例子里面的数据量比较少,实际上a文件和b文件都在4-5千万的数量级别。

问题补充:强调这两个文件加起来的数据有上亿条,估计导入到数据库都要很长时间。
现在的限制最多在2个小时以内完成对比,并输出相关的结果。

问题补充:
huzhenyu 写道
其实这玩意并不是特定的方式去处理,首先你得确定你id是否就是按顺序排列的,如果无序的你会搞到死.如果有序其它很好办怎么玩怎么有,用BufferInputStrem读进来一个一个比都完全可以.

是无序排列的。如果有序的话,也没这么多问题了。

问题补充:
mobilezht 写道
cat file1 file2 | sort |uique -c |grep -v ^2

合并文件,排序,计数,将只出现一次的记录行 列出来
(排除一样的记录行)

相信操作系统自带的这些工具比你现写程序的效率要高很多。尤其是不需要反复调试

确认一下是
cat a.txt b.txt | sort | unique -c | grep -v ^2

我运行了一下,说unique是无效命令?
我的cat版本是5.93
2011年4月15日 11:03

23个答案 按时间排序 按投票排序

0 0

我觉得 svn  。。这个东西。。 他的比较模式。。你可以去参考一下。。。。

。。

2011年4月29日 14:58
0 0

以下是针对有oracle环境的处理方式

1.用java程序把不必要的字段过滤掉,只保留主键,状态两个字段的数据,
  同时把一个大的文件才分成10份。
 
  这时候 a.txt,变成了 a1.txt,a2.txt,a3.txt..........a10.txt
 
2. 在oracle中建立一个a表

3. 新建4个控制文件平分了数据文件a1.txt,a2.txt,a3.txt..........a10.txt 的数据,

   在oracle  sqlldr 加入 errors=10000 direct=y  parallel=true 参数,启动并行导入模式


4. 用sql对比

 

2011年4月28日 15:52
0 0

#只在$1中有的行  
awk '{if(ARGIND==1) {v[$0]}else{if($0 in v)  delete v[$0]}}END{for(i in v) print i}' $1 $2  
#同时在$1和$2中的行   
awk '{if(ARGIND==1) {v[$0]}else{if($0 in v) print $0}}' $1 $2 

2011年4月27日 00:39
0 0

估算了一下,你一个文件上亿条记录,假如有2一条记录,文件大小应该在20G左右。根据个人经验,超过200万条不考虑使用Map,jvm使用heap就大概有300M,我们这里工作的同事一部分喜欢使用内存数据库,一部分牛人使用NIO自己设计存储排序方案。
给点提示:使用NIO,并行计算jrs166。

2011年4月26日 17:48
0 0

uniq -c

uniq 是计算重复的数量,合并重复的行

2011年4月26日 11:45
0 0

这么大的文件比较,想起来就头疼。能不能从业务的角度优化一下,把大文件拆小。

实在要比,有个比较偷懒的办法,就是用数据库。把数据插进数据库,SQL语句就可以处理了。上亿的文件如果都读进内存,再加上其他的业务数据,服务器容易宕机。

内存比较其实我想到个中性办法:把数据按照id逐条灌入memcached,借用memcached缓存的功能做逐条比较。

这种头疼的任务,最好能够避免。

2011年4月25日 19:23
0 0

内存放不下就分段作,按照ID 分发到成10个或者100个小文件中,然后对相同ID段的小文件在内存中先排序后比较。

2011年4月25日 14:34
0 0

相信我,我虽然没做过4-5千万,4-5百万的 比较做过N 多次。

2011年4月25日 13:34
0 0

cat file1 file2 | sort |uique -c |grep -v ^2

合并文件,排序,计数,将只出现一次的记录行 列出来
(排除一样的记录行)

相信操作系统自带的这些工具比你现写程序的效率要高很多。尤其是不需要反复调试

2011年4月25日 13:31
0 0

你要明白你不是比较文件差异而是比较记录集的差异
这两种场景处理方式完全不同

2011年4月24日 19:53
0 0

看你的数据格式 可以考虑用oracle的sql loader 先导入到临时表 然后进行比较

2011年4月24日 02:31
0 0

将两个文件读入缓存,用map分别存储为mapA和mapB,
迭代mapA,然后利用mapB.containsKey(mapA_key)判断即可。

如果mapB中有的,mapA中没有,貌似上述方法判断不出来。

2011年4月21日 17:49
0 0

2小时的时间足够了的,基本还是要看内存能用多少,如果可以,把a.txt读进去,以id为key,整个record string为value建立hashmap。然后读取b。txt,每读一行就去a。txt的hashmap看看id是否存在,然后根据情况比较久可以。
每个文件估计1.5g左右,就算安10M/s也只要150秒,其实跑起来半个小时应该就可以。算法的负责度估计是O(n*log(n)),不会慢的。

如果内存不够的话,就要对a.txt里的record做index处理,比较的时候使用index去定位文件来读取对应的record,不过也只是相当于把a。txt读两次,但需要内存可以减少1/2以上,具体要看每行record的长度。这样处理的话时间也不会超过一小时。

2011年4月20日 10:26
0 0

找个精通算法的人做吧

2011年4月19日 09:42
0 0

貌似现成的技术做不到.

2011年4月18日 13:53
0 0

可以自己百度上面找----比较文件差异工具

我帮忙找了几个:

http://www.oschina.net/p/diffuse/similar_projects

http://www.iplaysoft.com/winmerge.html
http://www.lupaworld.com/proj-cont-id-1190-bpage-2.html

上面三个没有你适合用的话,你就自己找找。。。

2011年4月16日 16:17
0 0

这么大的文件早就应该放到数据库里,让数据库管理,到不是不能写,但写成的,没问题几乎你是办不到的就好象为什么一个ORACLE做了这么多年才做成现在的样子

2011年4月16日 09:09
0 0

4 5千万就不该保存在两个单独的文件里...

现在这样首先肯定是要分别排序  不然不可能有高效的方法

2011年4月15日 22:02
0 0

晕。是4-5千万,我还以为是4,5万,这个就没必要了吧。那么大的数据,就是你读文件就要读个把小时。

2011年4月15日 16:13
0 0

其实这玩意并不是特定的方式去处理,首先你得确定你id是否就是按顺序排列的,如果无序的你会搞到死.如果有序其它很好办怎么玩怎么有,用BufferInputStrem读进来一个一个比都完全可以.

2011年4月15日 14:06
0 0

如果是我的话会用数据库,把两个文件加到同一张表里,然后加一个额外字段区分天数,然后用sql轻松搞定。

2011年4月15日 12:20
0 0

兄弟没必要去写这种东西,用现成的工具.比如svn用它的差分就可以得出结果.还有一些其它的成熟文本比较工具,你查下就知道了.

2011年4月15日 12:05
0 0

将两个文件读入缓存,用map分别存储为mapA和mapB,
迭代mapA,然后利用mapB.containsKey(mapA_key)判断即可。

2011年4月15日 11:09

相关推荐

Global site tag (gtag.js) - Google Analytics