`

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

 
阅读更多

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

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

Input,A:

asdfasdf

asdfasdBCasdfEFasd

 

output:

asdfasdf

asdfasdBCasdfEGasd

 

这个文件有500w+行。

最开始用如下脚本解决:

 

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替换掉,见如下:

 

 

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的方式来做:

 

#!/bin/awk -f

{
    if(match($0,"BC")){
        print gsub("EF","EG");
    }
    else{
        print $0;
    }
}

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

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

 

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

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

 

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

 

 

 

2
1
分享到:
评论
1 楼 orange666 2016-08-15  
直接用sed呗
$wc -l input.txt
5000002 input.txt

$time sed 's/BC/EG/g' input.txt > out.txt

real 0m7.550s
user 0m7.407s
sys 0m0.142s



相关推荐

    【shell】遍历文件夹下所有文件

    对linux命令tree的简单实现,遍历指定文件夹下的所有文件

    shell 脚本遍历目录

    采用shell脚本实现遍历文件并将文件打印到标准输出的小脚本,主要是学习。

    详解shell 遍历文件夹内所有文件并打印绝对路径

    通过本文的学习,我们不仅了解了如何使用Shell脚本遍历文件夹并打印出所有文件的绝对路径,还学习了一种递归的方法来处理多级目录。这种方法在很多场景下都非常有用,希望对你有所帮助。如果你在实践中遇到任何问题...

    Shell脚本实现从文件夹中递归复制文件

    ### Shell脚本实现从文件夹中递归复制文件 #### 背景介绍 在日常工作中,有时我们可能需要从多层嵌套的文件夹结构中提取特定的文件或者进行数据整理工作。对于这种需求,手动操作显然是低效且耗时的。此时,利用...

    shell 递归遍历目录下的所有文件并统一改名的方法

    # 遍历文件列表 for f in $flist; do if [ -d "$f" ]; then # 如果是目录,则继续递归调用 travFolder "$f" else # 如果是文件,则调用重命名函数 changeName "$f" fi done # 返回上级目录 cd ../ } `...

    遍历磁盘目录,遍历所有文件

    例如,在Windows系统中,可以使用`FindFirstFile`、`FindNextFile`和`FindClose`等API来遍历文件;在Linux或Unix系统中,可以使用`opendir`、`readdir`和`closedir`等函数进行操作。 以C++为例,遍历磁盘目录的代码...

    利用shell脚本遍历文件夹内所有的文件并作整理统计的方法

    Shell脚本是一种强大的工具,它允许我们自动化Linux或Unix系统中的文件处理任务。在这个案例中,我们将看到如何通过递归方法遍历文件夹结构,以及如何根据文件名的特定部分进行统计分析。 首先,我们创建一个名为`...

    遍历并显示回收站中的文件

    遍历回收站中的文件主要通过以下几种方法: 1. **图形界面操作**:用户可以通过双击桌面上的“回收站”图标打开回收站窗口,然后在窗口中看到所有被删除的文件和文件夹,包括它们的名称、大小、删除日期等信息。...

    Shell脚本用for循环遍历参数的方法技巧

    在Shell脚本编程中,有时候我们需要处理多个命令行参数,这时使用`for`循环来遍历这些参数就显得非常实用。本文将详细讲解如何在Shell脚本中使用`for`循环遍历参数,并介绍其中的一些小技巧。 1. **基本的参数遍历*...

    shell脚本读文件方法和例子

    ### Shell脚本读取文件的...Shell脚本提供了多种读取文件的方式,每种方法都有其适用场景。理解这些基本原理和技巧对于编写高效且易于维护的Shell脚本至关重要。希望本文能帮助您更好地掌握Shell脚本读取文件的方法。

    shell备份文件、重命名文件、删除指定文件的3个脚本分享

    本文将详细解析三个实用的Shell脚本,分别是用于备份文件、重命名文件和删除指定文件的脚本,适合初学者参考和实践。 1. 备份文件的脚本: ```bash #!/bin/bash E_BADARGS=65 case $# in 0) echo "message:param ...

    shell脚本递归遍历目录及子目录的例子分享

    总结来说,这三个实例都展示了如何使用Shell脚本递归遍历目录和子目录,以及如何处理这些目录中的文件。递归遍历目录在很多场景下都非常实用,比如备份文件、统计文件信息、清理或重命名文件等。理解并掌握这种技术...

    shell十三问

    - Shell支持多种条件测试,如文件测试(-f、-d等)、数值比较(-eq、-ne等)和字符串比较(=、!=等)。 - `if`语句结合`test`或`[ ]`命令进行条件判断,如`if [ -f "$FILE" ]; then ... fi`。 4. **流程控制** -...

    Shell脚本遍历一个日期范围实例

    在IT领域,Shell脚本是一种常用的自动化工具,尤其在Linux或Unix系统中,它能帮助我们执行一系列命令,包括处理文件、系统管理以及各种复杂的任务。在这个实例中,我们将探讨如何使用Shell脚本来遍历一个特定的日期...

    使用Shell遍历目录及其子目录中的所有文件方法

    在Linux或Unix操作系统中,Shell脚本是一种强大的工具,它允许用户通过命令行接口执行一系列自动化任务。在本文中,我们将深入探讨如何使用Shell脚本来遍历目录及其子目录中的所有文件。这种方法对于批量处理、文件...

    遍历磁盘目录.rar

    例如,使用C#的`DirectoryInfo`类,我们可以创建一个实例,然后调用`GetFiles()`和`GetDirectories()`方法来获取当前目录下的文件和子目录,并递归地遍历它们。 在Linux或Unix环境中,shell脚本如bash可以使用`for`...

    shell脚本实现linux系统文件完整性检测

    本文将详细介绍如何利用Shell脚本实现Linux系统文件完整性检测,并通过计算MD5校验和的方法来验证文件是否被篡改。 #### 关键概念解释 1. **文件完整性检测**: 是一种安全技术,用于检测关键文件是否被未经授权地...

    Shell脚本遍历目录并批量修改文件编码

    在将windows上的jsp网页移植到linux环境中时,发现一个个的转换编码及修改默认编码类型太慢,写此脚本进行尝试文件遍历~ 好久不写,手生了。 代码如下: #!/bin/bash # # SPATH=”/root/chengji/WebRoot” DPATH=”/...

Global site tag (gtag.js) - Google Analytics