Perhaps not the fastest :) [1], but it will do what you want, I believe:
for line in $(grep -n '^\[.*\]$' sections.txt | sort -k2 -t: | cut -f1 -d:); do tail -n +$line sections.txt | head -n 5 done
It's better here:
for pos in $(grep -b '^\[.*\]$' sections.txt | sort -k2 -t: | cut -f1 -d:); do tail -c +$((pos+1)) sections.txt | head -n 5 done
[1] The first is something like O (N ^ 2) in the number of lines in the file, since it should read the entire path to the section for each section. The second, which can immediately search for the correct position of the character, should be closer to O (N log N).
[2] This leads to your word that in each section there are always exactly five lines (heading plus the next four), therefore head -n 5 . However, it would be very easy to replace this with something that was read before, but did not include the next line starting with "[", in the case when it will ever be necessary.
Saving the beginning and the end requires a bit more work:
# Find all the sections mapfile indices < <(grep -b '^\[.*\]$' sections.txt)
You might want to make a function or script file out of this by changing section.txt to $ 1 everywhere.
source share