2

I want to search for pattern and if matched then print the matched line and previous line. I used code

awk '/pattern/ {print a}{a=$0}' file

But it is only printing the previous line of matched line. How can I print print previous line along with matched line.

Shreya
  • 639
  • 4
  • 11
  • what should it do if the match is on the first very line? – Daemon Painter Feb 23 '21 at 08:38
  • btw: use a variable, store previous $0, update it at the end of the loop, print when needed. – Daemon Painter Feb 23 '21 at 08:38
  • 1
    Any reason why you don't use `grep -B1 pattern`? – Quasímodo Feb 23 '21 at 11:57
  • [edit] your question to replace "pattern" with "partial-or-full string-or-regexp", whatever you actually mean (see https://stackoverflow.com/q/65621325/1745001). Also include a [mcve] with concise, testable sample input and expected output. Make sure it covers all of the non-obvious and non-trivial cases such as the regexp (if that's what it is) matching on the first line of input, the regexp matching on 2 consecutive lines, the regexp and input containing metachars, the regexp partial matching parts of the input, blank lines and lines of `0` in the input, etc., etc. – Ed Morton Feb 23 '21 at 17:40

3 Answers3

4

In your current approach, when the pattern matches you are first printing a and then set it to the value of the current line.

The effect of this is that a always has the value of the previous line. If the match is on the first line, you will print an empty string as a has no value yet.


Besides remembering the current line in a and printing it in the next iteration, you also have to print the current line $0 when the pattern matches.

awk '/pattern/ {
  if (a) print a
  print $0
}
{
  a=$0
}' file

If the value of a can also be an empty string or evaluate numerically to zero as pointed out in the comments by Ed Morton, you can start printing a from the second row on.

awk '
/regexp/ {
  if(FNR>1) { print a }
  print $0
}
{
  a=$0
}' file
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
4

You were close:

awk '/regexp/{print a $0}{a=$0 ORS}' file

See How do I find the text that matches a pattern? and in future remember to include sample input/output in your question.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
3

You are on right path, You forgot to print the current line simply do.

awk '
/pattern/{
  if(prev)  { print prev ORS $0 }
  if(FNR==1){ print             }
  next
}
{
  prev=$0
}
' Input_file

I have also taken care of 1st first line here, in case pattern comes in very first line then it will simply print that line, since there is no previous line.

Explanation: Adding detailed explanation for above.

awk '                                 ##Starting awk program from here.
/pattern/{                            ##Checking for specific pattern here.
  if(prev)  { print prev ORS $0 }     ##Checking if prev is NOT NULL then print prev newline current line.
  if(FNR==1){ print             }     ##Checking if its first line then simply print the line.
  next                                ##next will skip all further statements from here.
}
{
  prev=$0                             ##Setting prev to current line here.
}
' Input_file                          ##Mentioning Input_file name here.
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93