sed match pattern and print two lines before pattern and all lines upto end of file

Viewed 96

sample

tyu
abc

def
ghi
fgg
yui

Output

abc

def
ghi
fgg
yui

Matching pattern : ^def Print two lines before matching line including pattern and print all lines after pattern until end

3 Answers

1st solution: With your shown samples try following awk code, written and tested in GNU awk.

awk -v RS='(^|\n)def.*' '
RT{
  num=split($0,arr,ORS)
  sub(/\n$/,"",RT)
  print arr[num-1] ORS arr[num]  RT
}
' Input_file


2nd solution(More Generic one): In this solution one could mention number of lines needed to be printed before a match is found in awk's variable named lines and we need NOT to hardcode number of times we need to print array's element(in split function for first line).

awk -v lines="2" -v RS='(^|\n)def.*' '
RT{
  val=""
  num=split($0,arr,ORS)
  sub(/\n$/,"",RT)
  for(i=lines;i<=num;i++){
    val=(val?val ORS:"") arr[i]
  }
  print val RT
}
'  Input_file

Would you please try the following:

awk '
    f {print; next}                     # if the flag f is set, print the line
    {que[NR % 3] = $0}                  # store the line in a queue
    /^def/ {                            # if the pattern matches
        f = 1                           # then set the flag
        for (i = NR - 2; i <= NR; i++)  # and print two previous lines and current line
            print que[i % 3]
    }
' input_file.txt

This might work for you (GNU sed):

sed '1N;N;/def/!D;:a;n;ba' file

Open a window of 3 lines and if the desired string is not present, delete the first and append another until a match is found.

Then print those lines and all other lines to the end of the file.

N.B. This will start printing as soon a match is found, even if the match is in the first or second lines. If the match must be in the third or subsequent lines, use:

sed '1N;N;/def[^\n]*$/!D;:a;n;ba' file
Related