2

This question is similar to How to show lines after each grep match until other specific match? thus answers may be similar to those there.

I am trying to grab and extract from a file the lines that are after the lines that are matching a TARGET value ("forms=2", in my case) and the next empty line. The segment of my file is like below:

forms=1
Code=00416T0
Code=00416T0

forms=2       #Target**
Code=06538T0  #grab this line
Code=06538T0  #grab this line
Code=11288T0  #grab this line
Code=11288T0  #grab this line

forms=1
Code=00549T0
Code=00549T0
Code=00549T0

forms=2      #Target**
Code=00553T0 #grab this line
Code=02576T0 #grab this line
Code=02576T0 #grab this line

forms=1
Code=11099T0 

So I would like to find a way according to Target "forms=2" to have the following lines even if same of those grabbing lines are identical

Code=06538T0 #grab this line
Code=06538T0 #grab this line
Code=11288T0 #grab this line
Code=11288T0 #grab this line
Code=00553T0 #grab this line
Code=02576T0 #grab this line
Code=02576T0 #grab this line

Any help please?

2
  • possible duplicate of How to show lines after each grep match until other specific match? Commented Mar 1, 2014 at 11:10
  • @Mat I guess that you need a better duplicate; the referenced one includes the lines matching the pattern whereas in this case you need to exclude those. Commented Mar 1, 2014 at 11:58

3 Answers 3

2

The following might work for you:

sed -n '/forms=2/,/^[^C]/{/^[^C]/b;p}' filename

or, as suggested by Graeme:

sed -n '/^forms=2/,/^[^C]/ {/^Code=/p}' filename

For your input, it'd produce:

Code=06538T0  #grab this line
Code=06538T0  #grab this line
Code=11288T0  #grab this line
Code=11288T0  #grab this line
Code=00553T0 #grab this line
Code=02576T0 #grab this line
Code=02576T0 #grab this line

For handling cases where you might lines like form=20, you could say:

sed -n '/^forms=2\b/,/^[^C]/ {/^Code=/p}' filename    
4
  • This is good, I would do it like this though sed -n '/^forms=2/,/^[^C]/ {/^Code=/p}'. Only thing I can't figure out though is how to exclude sections with forms=20 without using extended regex. Commented Mar 1, 2014 at 11:31
  • @Graeme Yes, your suggestion makes sense. See the edit above for handling forms=20 case. Commented Mar 1, 2014 at 11:54
  • That works, I have no idea why though. \b is backspace, right? Commented Mar 1, 2014 at 12:02
  • 1
    @Graeme Word boundary. Commented Mar 1, 2014 at 12:03
1

Using perl:

%perl -lne 'if(/forms=2/.../^$/ and $_!~/forms=2|^$/){print}' file
Code=06538T0  #grab this line
Code=06538T0  #grab this line
Code=11288T0  #grab this line
Code=11288T0  #grab this line
Code=00553T0 #grab this line
Code=02576T0 #grab this line
Code=02576T0 #grab this line

Using awk:

awk '/forms=2/,/^$/{if(!/forms=2/&&!/^$/)print}' file

or:

awk '/^$/{flag=0};flag;/forms=2/{flag=1}' file

Using sed (GNU sed):

sed '/forms=2/,/^$/{//!b};d'
0

Another sed:

sed -n '/forms=2 /,/^$/ {/^.*forms.*$/d; /^$/d; s/  *#grab/ #grab/}' input

.

Code=06538T0 #grab this line
Code=06538T0 #grab this line
Code=11288T0 #grab this line
Code=11288T0 #grab this line
Code=00553T0 #grab this line
Code=02576T0 #grab this line
Code=02576T0 #grab this line
3
  • What if there was a line like this forms=20? Commented Mar 1, 2014 at 11:33
  • Also, I think this can be condensed to sed -n '/forms=2/,/^$/ {s/[ ][ ]*#grab/ #grab/p}'. You don't need to d if you already have -n, just add the p to the end of the substitution. Commented Mar 1, 2014 at 11:42
  • Thats is also what i was looking!! Commented Mar 3, 2014 at 10:36

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.