sed&awk杂记(一)

   sed和awk都是很强大的工具,有时间会找些联系题目来做,然后比较有趣的东西就记录下来了。代码都是别人写的,我只是做个记录罢了。

   怎么用awk实现grep -A3 -B3 B file的功能呢? 这个问题是在chinaunix shell板块看见的,思考了会,想到两种办法,一种是用一个数组存储所有的记录,当匹配到B时,输出B记录前后的行,这个办法的坏处是当数据量很大时,内存不够用。还有一种办法时用循环数组,只需要四个元素的数组,当匹配时,输出数组,然后清空,接着处理剩余的数据(可能会发生多次匹配)。

    利用循环数组的输出办法脚本如下:  

  
  
  
  
  1. BEGIN { Last_Range_End=0Range_End=0;  for(i=0;i<=3;i++)keep[i]="" } 
  2.  
  3.  
  4. {for(j=3;j>0;j--)keep[j]=keep[j-1];  keep[0]=$0} 
  5. NR<=Range_End { print $0 } 
  6.  
  7.  
  8.  
  9. /atime/{ Last_Range_End=Range_End; Range_EndNR + 3; 
  10.  
  11.                 if (  Last_Range_End < NR ) 
  12.                          { 
  13.                         non_intersect_lines=(4 - (NR - Last_Range_End) )>0? (NR - Last_Range_End) :4 ; 
  14.                         if(non_intersect_lines==4) print "--" ;   
  15.                         for(i=non_intersect_lines-1;i>=0;i--) print keep[i] 
  16.                         } 
  17.           } 

  

 还有种办法,没有使用数组,但是还没 看懂怎么实现的,是shell板块的一位大牛的方法: 

  
  
  
  
  1.     if (/B/) { 
  2.         if (!f) { 
  3.             if (p) { 
  4.                 if ( mN && NR - lpN > 3) print "--"; 
  5.                 print p; 
  6.                 p = ""
  7.             } 
  8.             f = !f; 
  9.         } 
  10.         mN = NR
  11.         print; 
  12.         lpN = NR
  13.     } else if (f) { 
  14.         if (NR-mN > 3) { 
  15.             f = !f; 
  16.             if (gsub(/\n/,"\n",p) > 1) sub(/[^\n]*\n/,"",p); 
  17.             pp = p?p"\n"$0:$0; 
  18.         } else { 
  19.             print; 
  20.             lpN = NR
  21.         } 
  22.     } else { 
  23.         if (gsub(/\n/,"\n",p) > 1) sub(/[^\n]*\n/,"",p); 
  24.         pp = p?p"\n"$0:$0; 
  25.     } 

  

   也许读读grep的源码,能有更好的思路。。。

 

你可能感兴趣的:(职场,grep,awk,休闲,功能)