优化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中

[python] view
plain
copy

  1. function while_read_LINE_FD_IN_AND_OUT
  2. {
  3. >$OUTFILE
  4. exec 3<&0
  5. exec 0< $INFILE
  6. exec 4<&1
  7. exec 1> $OUTFILE
  8. while read LINE
  9. do
  10. echo "$LINE"
  11. :
  12. done
  13. exec 1<&4
  14. exec 4>&-
  15. exec 0<&3
  16. exec 3>&-
  17. }

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

[python] view
plain
copy

  1. function while_LINE_line_FD_IN_AND_OUT
  2. {
  3. >$OUTFILE
  4. exec 3<&0
  5. exec 0< $INFILE
  6. exec 4<&1
  7. exec 1> $OUTFILE
  8. while LINE=`line`
  9. do
  10. echo "$LINE"
  11. :
  12. done
  13. exec 1<&4
  14. exec 4>&-
  15. exec 0<&3
  16. exec 3>&-
  17. }

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

[python] view
plain
copy

  1. function while_read_LINE_bottom_FD_OUT
  2. {
  3. >$OUTFILE
  4. exec 4<&1
  5. exec 1>$OUTFILE
  6. while read LINE
  7. do
  8. echo "$LINE"
  9. :
  10. done < $INFILE
  11. exec 1<&4
  12. exec 4>&-
  13. }

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

[python] view
plain
copy

  1. function while_read_LINE_bottom
  2. {
  3. >$OUTFILE
  4. while read LINE
  5. do
  6. echo "$LINE" >> $OUTFILE
  7. :
  8. done < $INFILE
  9. }

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

[python] view
plain
copy

  1. function for_LINE_cat_FILE_cmdsub2_FD_OUT
  2. {
  3. >$OUTFILE
  4. exec 4<&1
  5. exec 1> $OUTFILE
  6. for LINE in $(cat $INFILE)
  7. do
  8. echo "$LINE"
  9. :
  10. done
  11. exec 1<&4
  12. exec 4>&-
  13. }

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

[plain] view
plain
copy

  1. Method: function while_read_LINE_FD_IN_AND_OUT
  2. real    0m0.312s
  3. user    0m0.260s
  4. sys 0m0.036s
  5. Method: function while_LINE_line_FD_IN_AND_OUT
  6. real    0m6.347s
  7. user    0m0.000s
  8. sys 0m1.668s
  9. Method: function while_read_LINE_bottom_FD_OUT
  10. real    0m0.261s
  11. user    0m0.004s
  12. sys 0m0.256s
  13. Method: function while_read_LINE_bottom
  14. real    0m0.452s
  15. user    0m0.244s
  16. sys 0m0.204s
  17. Method: function for_LINE_cat_FILE_cmdsub2_FD_OUT
  18. real    0m0.623s
  19. user    0m0.388s
  20. sys 0m0.232s

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

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

时间: 2024-11-09 22:45:52

优化shell的文件读取操作的相关文章

python文件读取操作

1 #IO操作 2 #模拟账号登录 3 4 data = [] #0=userName 1=password 5 6 obj = open("login.txt","r") 7 for line in obj: 8 data.append(line.strip("\n")) 9 obj.close() 10 11 12 while True: 13 print("---------") 14 print("| 登录

Servlet-config.properteis资源文件读取操作

java文件 import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.Properties; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.h

Android学习--Assets资源文件读取及AssetManager介绍

APK安装过程 复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用数据目录,Android系统在sdcard上为每一个应用分配了存储路径:/sdcard/Android/data/$(应用的包路径),该路径可以通过 context.getExternalFilesDir 得到,一般应用卸载的时候,该目录也会随之被删除. Android资源文件分为两类: 第一种是res目录下存放

Shell按行读取文件的3种方法

Shell按行读取文件的方法有很多,下面写出三种方法: 写法一: #!/bin/bash #描述: # while循环读行操作 #作者:孤舟点点 #版本:1.0 #创建时间:2017-11-09 04:08:52 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH while read line do echo $line done < filename(待读取的文件) 写法二:

python 文件的写入和读取 操作

写入 >>>f = open('a.txt', 'w')>>>f.write('hello,')>>>f.write('iplaypython')>>>f.close()第一行:用写的方式打开a.txt这个文件,并赋给f      w 也可以写在前面 第二行:f.write方法写入( )括号内的内容第三行:同第二行意义相同,重点要说明下f.write写入的内容会追加到文件中已存在的数据后,也就是就此时的'iplaypython'是在'

Linux Shell脚本逐行读取多个文件

现有file1.file2.file3三个文件,其内容如下 $cat file1 f1_1 f1_2 f1_3 $cat file2 f2_1 f2_2 f2_3 $cat file3 f3_1 f3_2 f3_3 编写shell脚本逐行读取这三个文件 #!/bin/bash cat file1 file2 file3 |while read p   do     echo $p   done [思考] 采用done引入多个文件,怎么实现? #!/bin/bashwhile read p  do

Cocos2d-x操作:文件读取导致闪退

问题1:fopen 在vs下使用fopen进行文件处理,跑通了,但是移植到android下时就出现了一大推问题,首先需要理解的是在vs下开发资源是存放在执行文件的相同目录下的,而移植到android下时资源是存放在assets目录下的,之前尝试过使用以下的方法: char* fileName = "bg.png";  string filepath = [/font][/color]FileUtils::getInstance()[font=Arial]->fullPathFor

java常用工具类(三)—— 文件读取的操作类

定义常用的文件类型 public class FileType { /** * 文件头类型 */ public static final String XML_FILE = "text/xml;charset=UTF-8"; public static final String PDF_FILE = "application/pdf"; public static final String PDG_FILE = "application/x-png&quo

C# 文件操作 把文件读取到字节数组

string  zipfile = "c:\\a.zip";                            //方法1                            FileStream fs = new FileStream(zipfile, FileMode.Open);                            //把文件读取到字节数组                            byte[] zipdata = new byte[fs.Le