You could do this with sed. It's not ideal in that it doesn't actually understand records, but it might work for you...
sed -Ene 'H;${x;s/.*\nabc\nghi\n([0-9]+)\ndef\n.*/\1/;p;}' input.txt
Here's what's basically going on:
H
- appends the current line to sed's "hold space"
${
- specifies the start of a series of commands that will be run once we come to the end of the file
x
- swaps the hold space with the pattern space, so that future substitutions will work on what was stored using H
s/../../
- analyses the pattern space (which is now multi-line), capturing the data specified in your question, replacing the entire pattern space with the bracketed expression...
p
- prints the result.
One important factor here is that the regular expression is ERE, so the -E
option is important. If your version of sed uses some other option to enable support for ERE, then use that option instead.
Another consideration is that the regex above assumes Unix-style line endings. If you try to process a text file that was generated on DOS or Windows, the regex may need to be a little different.