Chinaunix首页 | 论坛 | 博客
  • 博客访问: 875514
  • 博文数量: 366
  • 博客积分: 10267
  • 博客等级: 上将
  • 技术积分: 4290
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-24 14:04
文章分类

全部博文(366)

文章存档

2012年(366)

分类: 系统运维

2012-03-16 17:43:20

昨天一个同事遇到一个需求:

有一个日志文件A,当日志文件中的某行包含某个字符串BC时,将字符串EF变成EG,并输出到新文件。即:

Input,A:

asdfasdf

asdfasdBCasdfEFasd

output:

asdfasdf

asdfasdBCasdfEGasd

这个文件有500w+行。

最开始用如下脚本解决:

Shell代码 复制代码 收藏代码
  1. cat $1 | while read line
  2. do
  3. echo $line | grep -q "BC"
  4. if [ $? -eq 0 ] ; then
  5. echo $line | sed "s/EF/EG/g" >> $1.out
  6. else
  7. echo $line >>$1.out
  8. fi
  9. done
cat $1 | while read line do echo $line | grep -q "BC" if [ $? -eq 0 ] ; then echo $line | sed "s/EF/EG/g" >> $1.out else echo $line >>$1.out fi done

上述脚本在循环中使用了grep、sed等外部命令,由于外部命令要fork一个process,因此效率极为低下。初步估计,运行完要25个小时以上。因此将循环中的grep和sed替换掉,见如下:

Shell代码 复制代码 收藏代码
  1. cat $1 | while read line
  2. do
  3. [[ "$line" == *"BC"* ]] && echo ${line/EF/EG} || echo ${line}
  4. done
cat $1 | while read line do [[ "$line" == *"BC"* ]] && echo ${line/EF/EG} || echo ${line} done

循环内部的代码简洁了很多,而且吧grep、sed等external command替换掉,在循环内部不会再有process 被fork出来。虽然执行效率提高很多,但也没有在我的耐心区间内得到结果,初步估算执行完需要半个小时以上。

问题应该不在循环内部,而是这种cat+while+read遍历文件内容的方式有问题。

换了awk的方式来做:

Awk代码 复制代码 收藏代码
  1. #!/bin/awk -f
  2. {
  3. if(match($0,"BC")){
  4. print gsub("EF","EG");
  5. }
  6. else{
  7. print $0;
  8. }
  9. }
#!/bin/awk -f { if(match($0,"BC")){ print gsub("EF","EG"); } else{ print $0; } }

这次效率有很大的提升,耗时18秒就出来了结果。

按理说这已经比较满足需求了。

不过,我的同事又试了另外一种方法,用perl解决问题:

--这段代码是我一个同事写的。

Shell代码 复制代码 收藏代码
  1. #!/usr/bin/perl
  2. open URLFILE, ">>aa";
  3. my $cnt=0;
  4. while (<>)
  5. {
  6. if (/BC/)
  7. {
  8. s/EF/EG/g;
  9. }
  10. print URLFILE $_;
  11. }
#!/usr/bin/perl open URLFILE, ">>aa"; my $cnt=0; while (<>) { if (/BC/) { s/EF/EG/g; } print URLFILE $_; }

这段代码的执行效率很高,比awk效果还要好,13秒。

按理说,就读取文件的效率来说,perl虽然很快但应该不会比awk快。

只是这个Perl中所做的工作只是读取文件的一行,而awk在读取完一行后,还要按照分隔符将$0划分成一个个字段,分别存在$1,,,$n中,只是,我们这个需求并没有用到这个功能,用awk解决这个需求还是有点大材小用了。

关于在shell下用什么方法来完成对文件的高效遍历,还有什么更好的方法吗?

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