Shell脚本用于打印与连续行上出现的模式匹配的行

时间:2013-12-13 01:47:28

标签: shell

我有大量文本文件,大小很大,并且使用shell脚本,想要搜索每个文件以识别字符串,例如“& abcdef”(表示每条记录的结尾),并且仅在发生时打印在连续的行中。

输入文件内容file-a,其中一个文件的示例;还有其他类似但巨大的文件:

1239560059   TAB001   
8E12222439   TAB001   
84dswe6059   &abcdef
8229559179   &abcdef
8012156059   TAB001  
804E122224   TAB001  
8046317400 20120629 233000  20120629 
8046005912   TAB001   
8046559179 23222333   &abcdef
80463174E9   TAB001    
8024360099   TAB001  
8046316343   955912   &abcdef
8439559149   &abcdef
8044360059   TAB001    
8046360059   TAB001    
8034395879   &abcdef

需要输出:

  • file-a的第3行和第4行在连续行中多次出现&abcdef
  • file-a的第12行和第13行在连续行中多次出现&abcdef

1 个答案:

答案 0 :(得分:2)

您可以使用awk跟踪之前和当前发生的事件,如果它们彼此相邻,则打印两行。

awk 'BEGIN {prev=0} /&abcdef/ {if(prev==0) {prev=NR;line=$0} else {if((prev+1)==NR) {print line;print $0}; prev=NR; line=$0}}' file-a

BUGS:有一个。如果有一对以上的出现,例如第11,12,13行出现,代码将打印第11,12,12,13行。否则它将打印好对。

如果您希望文件中出现超过2行& abcdef,请告诉我,我将修改此代码以便对其进行处理。

编辑:忘记在代码中包含文件名。

编辑:这是非常简陋的,绝对可以改进。这是修改后的代码。

awk 'BEGIN {prev=0} /&abcdef/ {if(prev==0) {prev=NR;line=$0; print FILENAME} else {if((prev+1)==NR) {print NR-1 ":" line;print NR ":" $0}; prev=NR; line=$0}}' file-a

编辑:如果您希望文件名预先填写,就像行号一样,那么您的代码应该是。

awk 'BEGIN {prev=0} /&abcdef/ {if(prev==0) {prev=NR;line=$0} else {if((prev+1)==NR) {print FILENAME ":" NR-1 ":" line;print FILENAME ":" NR ":" $0}; prev=NR; line=$0}}' file-a

编辑:如果您只需要打印文件名和行号而不是行本身,那么您的代码应该是:

awk 'BEGIN {prev=0} /&abcdef/ {if(prev==0) {prev=NR;line=$0} else {if((prev+1)==NR) {print FILENAME ":" NR-1;print FILENAME ":" NR}; prev=NR; line=$0}}' file-a