Unix help to extract/print 50 lines after every 3r

2019-09-17 07:59发布

问题:

I need help with extract/print 4 lines after every 3rd occurrence pattern till end of file. Consider below is example of log file

ERROR_FILE_NOT_FOUND
ERROR_FILE_NOT_FOUND
ERROR_FILE_NOT_FOUND
Extract line 1
Extract line 2
Extract line 3
Extract line 4

ERROR_FILE_NOT_FOUND
ERROR_FILE_NOT_FOUND
ERROR_FILE_NOT_FOUND
Extract line 5
Extract line 6
Extract line 7
Extract line 8

ERROR_FILE_NOT_FOUND
ERROR_FILE_NOT_FOUND
ERROR_FILE_NOT_FOUND
Extract line 9
Extract line 10
Extract line 11
Extract line 12

回答1:

Just use some flags to keep track of what appeared and how many times:

awk -v patt="ERROR_FILE_NOT_FOUND"
    'lines==3 {print; appeared++}
     appeared==4 {lines=0;appeared=0}
     patt~$0 {lines++}' file

Explanation

This keeps loading lines as number of lines matched. Once it has reached 3, starts printing. It prints exactly 4 times.

  • -v patt="ERROR_FILE_NOT_FOUND" this provides the pattern to be looked at
  • lines==3 {print; appeared++} if the counter lines is 3, print the line and start counting how many lines have appeared.
  • appeared==4{lines=0;appeared=0} if the number of lines that have been printed is already 4, reset the flags to 0.
  • patt~$0 {lines++} if the line matches the pattern given, increment the variable lines.

Note all these constants 3 and 4 could be put outside with -v as well, to make it more generic:

awk -v patt="ERROR_FILE_NOT_FOUND" -v matches=3 -v lines_to_print=4
    'lines==matches {print; appeared++}
     appeared==lines_to_print {lines=0;appeared=0}
     patt~$0 {lines++}' file

Test

$ awk -v patt="ERROR_FILE_NOT_FOUND" 'lines==3 {print; appeared++} appeared==4 {lines=0;appeared=0} patt~$0 {lines++}' file
Extract line 1
Extract line 2
Extract line 3
Extract line 4
Extract line 5
Extract line 6
Extract line 7
Extract line 8
Extract line 9
Extract line 10
Extract line 11
Extract line 12