Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1484046
  • 博文数量: 263
  • 博客积分: 10851
  • 博客等级: 上将
  • 技术积分: 2627
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-26 22:40
文章分类

全部博文(263)

文章存档

2013年(4)

2012年(25)

2011年(33)

2010年(50)

2009年(138)

2008年(13)

分类: LINUX

2009-09-22 12:03:25

工作中经常碰上这种情况,需要提取存在于小文件a第1列而不存在于大文件b第1列的数据, 这个可以用awk很快写出代码

awk -F \| '{ if(NR == FNR){userid[$1]=1;} else {if(userid[$1]!=1) print $1;} }' b a

但是,如果文件b(通常情况下b是用户表备份文件)比较大时这个代码就会出现内存溢出的问题了, 这种情况下我们很容易想到,既然b不能全部放在内存,那就倒过来把a放在内存吧,于是会有下面的代码:

awk -F \| '{ if(NR == FNR){userid[$2]=1;} else {if(userid[$1]==1)userid [$1]=0;} } END{for (i in userid){if(userid[i])print i}}' a b

但是,事实证明,这样的代码也不行,因为awk里的数组跟c++的map一样,通过下标访问时就会占存储空间,所以这段代码其实最终也会把b全部存到内存

怎么办呢?方法很多:

1 把b分成两(或更多)部分,依次进行查找
awk -F \| '{ if(NR == FNR){userid[$2]=1;} else  if(FNR < 100000)  {if(userid[$1]==1)userid[$1]=0;} }  END{for (i in userid){if(userid[i])print i}}' a b > c

awk -F \| '{ if(NR == FNR){userid[$2]=1;}  else  if(FNR >= 100000) {if(userid[$1]==1)userid[$1]=0;} }  END{for (i in userid){if(userid[i])print i}}' c b

或者 awk -F \| '{ if(NR == FNR && NR < 10000){userid[$1]=1;} else {if(userid[$1]!=1) print $1;} }' b a > c

awk -F \| '{ if(NR == FNR && NR >= 10000){userid[$1]=1;} else {if(userid[$1]!=1) print $1;} }' b a > c


2 利用awk的in操作符代替if(userid[$1]==1)

awk -F \| '{ if(NR == FNR){userid[$2]=1;} else {if($1 in userid) delete userid[$1];} } END{for (i in userid){if(userid[i])print i}}' b a > d

阅读(3493) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~