Reputation: 33
I need extract blocks (between two words: Start and End) of text containing an other word (id).
For example:
2014-07-01 13:26:07,760 Start
2014-07-01 13:26:07,762 id: 456456454
2014-07-01 13:26:07,763 other
2014-07-01 13:26:07,764 End
2014-07-01 13:26:07,764 aaaaaaaa
2014-07-01 13:26:07,764 bbbbbbbb
2014-07-01 13:26:07,765 Start
2014-07-01 13:26:07,765 id: 930939023
2014-07-01 13:26:07,765 something
2014-07-01 13:26:07,766 End
2014-07-01 13:26:07,766 Start
2014-07-01 13:26:07,766 id: 876542
2014-07-01 13:26:07,766 other
2014-07-01 13:26:07,767 End
2014-07-01 13:26:07,767 aaaaaaaa
2014-07-01 13:26:07,767 bbbbbbbb
2014-07-01 13:26:07,767 Start
2014-07-01 13:26:07,767 id: 930939023
2014-07-01 13:26:07,768 something
2014-07-01 13:26:07,768 End
2014-07-01 13:26:07,768 Start
2014-07-01 13:26:07,768 id: 54654
2014-07-01 13:26:07,768 something
2014-07-01 13:26:07,769 End
For id = 930939023, the output is
2014-07-01 13:26:07,765 Start
2014-07-01 13:26:07,765 id: 930939023
2014-07-01 13:26:07,765 something
2014-07-01 13:26:07,766 End
2014-07-01 13:26:07,767 Start
2014-07-01 13:26:07,767 id: 930939023
2014-07-01 13:26:07,768 something
2014-07-01 13:26:07,768 End
Upvotes: 3
Views: 402
Reputation: 158280
You can use awk
. Because the script will get more complicated I suggest to store it in a file:
extract.awk:
# Set flag if id was found
/id: 930939023/{f=1}
# On "Start" clear the buffer, reset buffer index i and reset flag
/Start/{b=$0;f=0;next}
# On "End", if the flag was set print the buffer
/End/{
if(f){
print b
print
}
}
# Append all other lines to buffer
# (Lines between start end will get cleared on next "Start")
{b=b"\n"$0}
... and execute it like this:
awk -f extract.awk file
Output:
2014-07-01 13:26:07,765 Start
2014-07-01 13:26:07,765 id: 930939023
2014-07-01 13:26:07,765 something
2014-07-01 13:26:07,766 End
2014-07-01 13:26:07,767 Start
2014-07-01 13:26:07,767 id: 930939023
2014-07-01 13:26:07,768 something
2014-07-01 13:26:07,768 End
Upvotes: 1
Reputation: 174874
You could try the below awk command,
$ awk '/Start/ {f=1} /End/ {print;f=0;}f' file | awk -v RS="End" -v ORS="End" '/930939023/'
2014-07-01 13:26:07,765 Start
2014-07-01 13:26:07,765 id: 930939023
2014-07-01 13:26:07,765 something
2014-07-01 13:26:07,766 End
2014-07-01 13:26:07,767 Start
2014-07-01 13:26:07,767 id: 930939023
2014-07-01 13:26:07,768 something
2014-07-01 13:26:07,768 End
Upvotes: 1
Reputation: 77185
Here is an option using sed
:
sed -n '/Start/{:a;/End/!{N;ba};/930939023/!d;p}' file
sed -n ' # Suppress default printing
/Start/ { # When line contains Start
:a; # Create a label a for loop
/End/! { # Until a line with End is seen
N; # Append the next line to pattern space
ba # Go back to label a and repeat
}
/930939023/!d; # If the appended line contains does not contain id, delete it
p # Else print it
}' file
Upvotes: 7