Linux shell逐行读取文件的方法

时间:2022-08-02 21:48:36
  1. 在linux中有很多方法逐行读取一个文件的方法,其中最常用的就是下面的脚本里的方法,而且是效率最高,使用最多的方法。为了给大家一个直观的感受,我们将通过生成一个大的文件的方式来检验各种方法的执行效率。  
  2. 方法1:while循环中执行效率最高,最常用的方法。  
  3.    
  4. function while_read_LINE_bottm(){  
  5.  While read LINE  
  6.  do  
  7. echo $LINE  
  8. done   < $FILENAME  
  9. }  
  10.    
  11.          注释:我习惯把这种方式叫做read釜底抽薪,因为这种方式在结束的时候需要执行文件,就好像是执行完的时候再把文件读进去一样。  
  12.    
  13. 方法2 : 重定向法;管道法: cat $FILENAME | while read LINE  
  14.    
  15. Function While_read_LINE(){  
  16.  cat $FILENAME | while read LINE  
  17.  do  
  18. echo $LINE  
  19. done  
  20. }  
  21.           注释:我只所有把这种方式叫做管道法,相比大家应该可以看出来了吧。当遇见管道的时候管道左边的命令的输出会作为管道右边命令的输入然后被输入出来。  
  22.    
  23. 方法3: 文件描述符法  
  24.    
  25. Function while_read_line_fd(){  
  26. Exec 3<&0  
  27. Exec 0<$FILENAME  
  28. While read LINE  
  29. Do  
  30.  Echo $LINE  
  31.  Exec 0<&<3  
  32. }  
  33.    
  34.          注释: 这种方法分2步骤,第一,通过将所有内容重定向到文件描述符3来关闭文件描述符0.为此我们用了语法Exec 3<&0 。第二部将输入文件放送到文件描述符0,即标准输入。  
  35.     
  36. 方法4    for  循环。  
  37.    
  38. function  for_in_file(){  
  39. For  i  in  `cat $FILENAME`  
  40. do  
  41. echo $i  
  42. done  
  43. }  
  44.            注释:这种方式是通过for循环的方式来读取文件的内容相比大家很熟悉了,这里不多说。  
  45.    
  46.    
  47.      对各个方法进行测试,看那方法的执行效率最高。  
  48.    
  49.            首先我们用脚本(脚本见附件)生成一个70000行的文件,文件位置在/scripts/bigfile。然后通过下面的脚本来测试各个方法的执行效率,脚本很简单,不再解释。  
  50.    
  51. #!/bin/bash  
  52. FILENAME="$1"  
  53. TIMEFILE="/tmp/loopfile.out" > $TIMEFILE  
  54. SCRIPT=$(basename $0)  
  55.    
  56. function usage(){  
  57. echo -e "\nUSAGE: $SCRIPT file \n"  
  58.    
  59. exit 1  
  60. }  
  61.    
  62. function while_read_bottm(){  
  63.    
  64. while read LINE  
  65. do  
  66. echo $LINE  
  67.    
  68. done < $FILENAME  
  69.    
  70. }  
  71.    
  72. function while_read_line(){  
  73.    
  74. cat $FILENAME | while read LINE  
  75. do  
  76. echo $LINE  
  77. done  
  78.    
  79. }  
  80.    
  81.  function while_read_line_fd(){  
  82.    
  83. exec 3<&0  
  84. exec 0< $FILENAME  
  85. while read LINE  
  86. do  
  87.  echo $LINE  
  88. done  
  89.  exec 0<&3  
  90. }  
  91.    
  92. function for_in_file(){  
  93. for i in   `cat $FILENAME`  
  94. do  
  95. echo $i  
  96. done  
  97. }  
  98.    
  99. if [ $# -lt 1 ] ; then  
  100. usage  
  101. fi  
  102.  echo -e " \n starting file processing of each method\n"  
  103.  echo -e "method 1:"  
  104.  echo -e "function while_read_bottm"  
  105.  time while_read_bottm >> $TIMEFILE  
  106.    
  107. echo -e "\n"  
  108.    
  109. echo -e "method 2:"  
  110. echo -e "function while_read_line "  
  111. time while_read_line >> $TIMEFILE  
  112.    
  113. echo -e "\n"  
  114. echo -e "method 3:"  
  115. echo "function while_read_line_fd"  
  116. time while_read_line_fd >>$TIMEFILE  
  117.    
  118. echo -e "\n"  
  119. echo -e "method 4:"  
  120. echo -e "function   for_in_file"  
  121. time   for_in_file >> $TIMEFILE  
  122.    
  123.      执行脚本后: [root@localhost shell]# ./while /scripts/bigfile  
  124. 脚本输出内容:  
  125. method 1:  
  126. function while_read_bottm  
  127.    
  128. real    0m5.689s  
  129. user    0m3.399s  
  130. sys     0m1.588s  
  131.    
  132.    
  133. method 2:  
  134. function while_read_line  
  135.    
  136. real    0m11.612s  
  137. user    0m4.031s  
  138. sys     0m4.956s  
  139.    
  140.    
  141. method 3:  
  142. function while_read_line_fd  
  143.    
  144. real    0m5.853s  
  145. user    0m3.536s  
  146. sys     0m1.469s  
  147.    
  148.    
  149. method 4:  
  150. function   for_in_file  
  151.    
  152. real    0m5.153s  
  153. user    0m3.335s  
  154. sys     0m1.593s  
  155.    
  156.    
  157. 下面我们对各个方法按照速度进行排序。  
  158. real    0m5.153s    method 4 (for 循环法)  
  159. real    0m5.689s    method 1   (while 釜底抽薪法)  
  160. real    0m5.853s    method 3    (标识符法)  
  161. real    0m11.612s   method 2     (管道法)  
  162.    
  163.  由此可见在各个方法中,for语句效率最高,而在while循环中读写文件时,  
  164. while read LINE  
  165. do  
  166. echo $LINE