打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Shell下三种遍历文件的方法比较

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

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

Input,A:

asdfasdf

asdfasdBCasdfEFasd

 

output:

asdfasdf

asdfasdBCasdfEGasd

 

这个文件有500w+行。

最开始用如下脚本解决:

 

cat $1 | while read linedo echo $line | grep -q "BC"if [ $? -eq 0 ] ; then echo $line | sed "s/EF/EG/g" >> $1.outelse echo $line >>$1.outfidone

 

 

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

 

 

cat $1 | while read linedo    [[ "$line" == *"BC"* ]] && echo ${line/EF/EG} || echo ${line}done

 

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

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

 

 

换了awk的方式来做:

 

#!/bin/awk -f{    if(match($0,"BC")){        print gsub("EF","EG");    }    else{        print $0;    }}

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

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

 

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

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

 

#!/usr/bin/perlopen 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下用什么方法来完成对文件的高效遍历,还有什么更好的方法吗?

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Linux Shell 文本处理工具集锦大CC | 大CC
shell编程范例之字符串操作 - wuye_chinaunix
超详细的5个shell脚本实例分享,值得收藏
shell大全
[汇总]shell笔试
linux Shell学习笔记第一天
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服