Print line, which is situated 2 lines before the match(pattern).
I tried next:
sed -n \': loop
/.*/h
:x
{n;n;/cen/p;}
s/./c/p
t x
s/n/c/p
t loop
{g;p
I've tested your sed command but the result is strange (and obviously wrong), and you didn't give any explanation. You will have to save three lines in a buffer (named hold space), do a pattern search with the newest line and print the oldest one if it matches:
sed -n '
## At the beginning read three lines.
1 { N; N }
## Append them to "hold space". In following iterations it will append
## only one line.
H
## Get content of "hold space" to "pattern space" and check if the
## pattern matches. If so, extract content of first line (until a
## newline) and exit.
g
/^.*\nsix$/ {
s/^\n//
P
q
}
## Remove the old of the three lines saved and append the new one.
s/^\n[^\n]*//
h
' infile
Assuming and input file (infile
) with following content:
one
two
three
four
five
six
seven
eight
nine
ten
It will search six
and as output will yield:
four
The script:
sed -n "1N;2N;/XXX[^\n]*$/P;N;D"
works as follows:
1N;2N
XXX
anywhere in the last line, and if found print the first line of the pattern space, P
N
D
, noting that 1N;2N
is no longer applicableIf you can use awk
try this:
awk '/pattern/ {print b} {b=a;a=$0}' file
This will print two line before pattern
Here are some other variants:
awk '{a[NR]=$0} /pattern/ {f=NR} END {print a[f-2]}' file
This stores all lines in an array a
. When pattern is found store line number.
At then end print that line number from the file.
PS may be slow with large files
Here is another one:
awk 'FNR==NR && /pattern/ {f=NR;next} f-2==FNR' file{,}
This reads the file twice (file{,}
is the same as file file
)
At first round it finds the pattern and store line number in variable f
Then at second round it prints the line two before the value in f
This might work for you (GNU sed):
sed -n ':a;$!{N;s/\n/&/2;Ta};/^PATTERN\'\''/MP;$!D' file
This will print the line 2 lines before the PATTERN
throughout the file.
This one with grep, a bit simpler solution and easy to read [However need to use one pipe]:
grep -B2 'pattern' file_name | sed -n '1,2p'