How to print different multiple lines after two patterns?

Hello,

I need to print some lines as explained below,
TXT example

1111
2222
3333
4444
5555
6666
7777
8888
6666
9999
1111
2222
3333
4444
5555
6666
7777
8888
6666
9999

Let's say I have two patterns 1111 and 6666 and one variable n (dynamic line numbers depending on file). Assume n=2 here, I want to print "2" lines after 1111 including the pattern 1111 and the second pattern line in the original order. The output should looks like,

1111
2222
3333--the above two line after first pattern
6666
6666
1111
2222
3333--the above two line after first pattern
6666
6666

I tried with grep -A2 -e '1111' -e '6666' TXT. It did the job partly right because it also prints two lines after the second pattern "6666", which are not wanted.

I thank you very much for your help!

Zhen

Got Perl?

perl -ne '/1111/ and $n=3; /6666/ and $n=1; print if $n-- > 0 ' liuzhencc.file
1111
2222
3333
6666
6666
1111
2222
3333
6666
6666

Thanks. I think perl is installed as default with Ubuntu 14. That's already very good to get job done with perl. Is that any possibility to use sed or awk? I suppose either sed or awk should be able to do this job. However, I cannot work it out.

Like so?

awk '$0 ~ P1 {L = NR + n} $0 ~ P2; NR <= L ' n=2 P1=1111 P2=6666 file
1111
2222
3333
6666
6666
1111
2222
3333
6666
6666

Many thanks. You are always come with a super concise, super smart script to solve the problem. May I kindly ask a further question on this problem? How to modified this script if I want to print "2" lines before 1111 including the pattern 1111 and the second pattern line in the original order. Then the output should look like,

1111-->only one line because there no line above 6666 
6666-->this line meets both patterns 
9999-->two lines before the first pattern '1111' 
1111
6666
6666 

Would that work?

awk '$1=="1111"{n=3} $1=="6666" && n<1{n=1} n-- > 0' liuzhencc.file

The easiest way would be to use my above proposal and reverse input and output:

tac file | awk '$0 ~ P1 {L = NR + n} $0 ~ P2 || NR <= L ' n=2 P1=1111 P2=6666 | tac
1111
6666
6666
9999
1111
6666
6666

Indeed, I thought about this. What if I have to print the previous m lines before a third pattern? That means it is a mixed process of backward search with pattern 3 and two forward searches with pattern 1 and pattern 2. I searched google and found it's a hard job to print multiple previous lines with awk.

Similar problems have been covered in these forums several times. How about giving it a go and come back with the solution should difficulties arise?

1 Like