9

I have a file prova.txt like this:

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4

extra1
extra2
bla

Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

extra2
bla
bla

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

and I need to grep out from "Start to grab here" to the first blank line. The output should be like this:

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4

Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

As you can see the lines after "Start to grab here" are random, so -A -B grep flag don't work:

cat prova.txt | grep "Start to grab from here" -A 15 | grep -B 15 "^$" > output.txt

Can you help me to find a way that catch the first line that will be grabbed (as "Start to grab from here"), until a blank line. I cannot predict how many random lines I will have after "Start to grab from here".

Any unix compatible solution is appreciate (grep, sed, awk is better than perl or similar).

EDITED: after brilliant response by @john1024, I would like to know if it's possible to:

1° sort the block (according to Start to grab from here: 1 then 1 then 2)

2° remove 4 (alphabetically random) lines fix1,fix2,fix3,fix4 but are always 4

3° eventually remove random dupes, like sort -u command

Final output shoul be like this:

# fix lines removed - match 1 first time
Start to grab from here: 1
random1
random2
random3
random4

#fix lines removed - match 1 second time
Start to grab from here: 1
#random1 removed cause is a dupe
random22131

#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561

or

# fix lines removed - match 1 first time and the second too
Start to grab from here: 1
random1
random2
random3
random4
#random1 removed cause is a dupe
random22131

#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561

The second output is better that the first one. Some other unix command magic is needed.

  • 1
    This is really helpful for grabbing the stack trace for a particular thread from java jstack output. Glad I found this Q&A! – BenjaminBallard Sep 14 '18 at 14:00
12

Using awk

Try:

$ awk '/Start to grab/,/^$/' prova.txt
Start to grab from here: 1
random1
random2
random3
random4

Start to grab from here: 2
random1546
random2561

Start to grab from here: 3
random45
random22131

/Start to grab/,/^$/ defines a range. It starts with any line that matches Start to grab and ends with the first empty line, ^$, that follows.

Using sed

With very similar logic:

$ sed -n '/Start to grab/,/^$/p' prova.txt
Start to grab from here: 1
random1
random2
random3
random4

Start to grab from here: 2
random1546
random2561

Start to grab from here: 3
random45
random22131

-n tells sed not to print anything unless we explicitly ask it to. /Start to grab/,/^$/p tells it to print any lines in the range defined by /Start to grab/,/^$/.

  • Your solution is perfect, I have edited my ask to add something. Relly apreciate your help. Thank you – heisen Oct 24 '16 at 19:08
0

I am posting an alternative solution as it may be useful to some peoples use cases. This solution does not comply exactly to the stated requirements, for the best solution see the answer from @John1024.

You can use awk with the Record Separator set to an empty string, awk will interpret these as blank newlines:

$ awk '/Start/' RS= prova.txt 
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

This version does not preserve the blank newlines in the output. It will also show context before the match if present. This behaviour can be very useful when grepping for something in a file and you want to see the newline delimited block it is a part of, for example:

$ awk '/random1546/' RS= prova.txt 
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

For example I find this useful when grepping for things in ini files.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.