Blockgrep splits standard input into blocks based on a separator string which can be a regular expression (BRE or ERE). It then searches for multiple patterns in each block. If a block contains at least one of the patterns then the whole block is printed.
This can be very useful when analyzing logs where multiple consecutive lines ("blocks") belong together, and you want to search for not only each single line that has a pattern but for whole blocks that contains patterns. This is frequently the case when you have huge logs and you need to reduce the logs to something manageable.
Consider this simple log file. Each block is started with the text "client .... :"
client A: get file foo put file baa client B: list users append to file foo client A: get file boo truncate file goo client C: create file goo append to file goo
Loading the file into your editor (or simply using less/more) is not a very efficient way for searching for information when the logs are large and what you are searching for is more than a simple pattern.
What is client A doing?
$ blockgrep "client.*:" "client A" <sample_log client A: get file foo put file baa client A: get file boo truncate file goo
When is file boo touched?
$ blockgrep "client.*:" "boo" <sample_log client A: get file boo truncate file goo
When is file baa or boo touched?
$ blockgrep "client.*:" "baa" "boo" <sample_log client A: get file foo put file baa client A: get file boo truncate file goo
When is client A touching file goo ?
blockgrep "client.*:" "client A" <sample_log | blockgrep "client.*:" "goo" client A: get file boo truncate file goo