天天看点

linux下shell读写文件优化操作总结

       前段时间经常在linux下对文件进行一些读取操作,可在操作得过程中发觉一些脚本的执行效率并不是很理想,下来认真的翻了一下《Mastering UNIX shell Scripting》,学习了一下其中对文件读取和写入得一些方法,在此进行总结记录。

       我们对文件得处理往往是通过循环得方式进行的,在循环中解析文件时,需要一种方法把整行得数据读入到一个变量中。最常见的命令是read。该命令很灵活,可用它读取单个字符串也可以读取整行。谈到读取整行,line是另一个可以读一行得命令。但一些操作系统并不支持line命令。除了read和line命令外,也需要查看一下while和for循环得不同方法,这是决定执行速度快慢得主要原因。在预定义得配置中可以把循环作为一个独立得循环来使用,可以用在命令管道中,也可以用文件描述符。每种方法有其自身得一套法则。如何利用循环得到最快得执行速度非常关键,也是决定一个处理文件脚本得关键因素。

       文件描述符:0 -stdin,1-stdout,2-stderr,在大多数操作系统中,有效得描述符的值为0到19,使用上述某些值时,必须做很多测试以便确认它们未被系统某种原因而保留。

        接下来我们通过一个shell中得time命令来测试不同方法处理文件的时间差,其中time会返回三个值分别为real user sys,代表得意思分别是: 总执行时间;用户/应用系统进程级花费得处理时间;系统在系统/内核级花费得处理时间,所有得计时数据都是输出到stderr或者标准错误,即文件描述符2,所以需要正确重定向标准错误输出进行查看。

        方法一:采用重定向标准输入,标准输出的方式。在处理中将标准输入重定向到文件描述附3,标准输出重定向到文件描述附4,并通过read逐行读取数据存入变量LINE中

function while_read_LINE_FD_IN_AND_OUT
{
    >$OUTFILE

    exec 3<&0
    exec 0< $INFILE

    exec 4<&1
    exec 1> $OUTFILE

    while read LINE
    do
        echo "$LINE"
        :
    done

    exec 1<&4
    exec 4>&-

    exec 0<&3
    exec 3>&-
}
           

       方法二,仍旧采用文件描述符,但是采用line命令,执行方法如下:

function while_LINE_line_FD_IN_AND_OUT
{
    >$OUTFILE

    exec 3<&0
    exec 0< $INFILE

    exec 4<&1
    exec 1> $OUTFILE

    while LINE=`line`
    do
        echo "$LINE"
        :
    done

    exec 1<&4
    exec 4>&-

    exec 0<&3
    exec 3>&-
}
           

     方法三,只重定向标准输出描述符,使用done<$INFILE输入重定向

function while_read_LINE_bottom_FD_OUT
{
    >$OUTFILE

    exec 4<&1
    exec 1>$OUTFILE
    while read LINE
    do
        echo "$LINE"
        :
    done < $INFILE

    exec 1<&4
    exec 4>&-
}
           

      方法四,不是用文件描述附:

function while_read_LINE_bottom
{
    >$OUTFILE

    while read LINE
    do
        echo "$LINE" >> $OUTFILE
        :
    done < $INFILE

}
           

     方法五,采用for循环的方式

function for_LINE_cat_FILE_cmdsub2_FD_OUT
{
    >$OUTFILE

    exec 4<&1
    exec 1> $OUTFILE

    for LINE in $(cat $INFILE)
    do
        echo "$LINE"
        :
    done

    exec 1<&4
    exec 4>&-
}
           

    以上五种方法测试mysql.txt的一个描述文件得时间对比如下:

Method: function while_read_LINE_FD_IN_AND_OUT
real	0m0.312s
user	0m0.260s
sys	0m0.036s

Method: function while_LINE_line_FD_IN_AND_OUT
real	0m6.347s
user	0m0.000s
sys	0m1.668s

Method: function while_read_LINE_bottom_FD_OUT
real	0m0.261s
user	0m0.004s
sys	0m0.256s

Method: function while_read_LINE_bottom
real	0m0.452s
user	0m0.244s
sys	0m0.204s

Method: function for_LINE_cat_FILE_cmdsub2_FD_OUT
real	0m0.623s
user	0m0.388s
sys	0m0.232s
           

       在对文件进行读取操作时,采用文件符明显快于不采用文件符的,采用read的快于采用line命令的,采用while循环读取文件的快于for循环的。

       在*nix平台上处理任何任务都有多种方法;一些文件处理技术浪费了大量得CPU时间,大多数浪费得时间花费在不必要得变量赋值以及连续地打开和关闭不同得文件上。在使用管道对循环计时也有负面影响,管道使用的文件大小最大不能超过2048个字符。

继续阅读