TL;DR- There's a lot going on in the sed pattern below, and I'm not sure how the discrete pieces are being composed into an overall command.
Bash version: GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin21)
I'm learning about shell scripting by reading the RBENV codebase file-by-file, and I've encountered the rbenv-help file, which includes this function definition:
extract_initial_comment_block() {
sed -ne "
/^#/ !{
q
}
s/^#$/# /
/^# / {
s/^# //
p
}
"
}
I see how this function is called further down in the code, so I know that its first arg is a filename:
extract_initial_comment_block < "$filename" | collect_documentation
From this I can see that the file represented by "$filename" is being fed as the standard input to the sed command. For the purposes of my question, the knock-on function "collect_documentation" is irrelevant.
I also gather from the name of the function that its purpose is to take a file like this, and return its summary and usage comments, i.e. lines 2-14 of the linked file. However, I haven't tested this theory yet, so I may not be 100% correct.
Furthermore, I know from this StackExchange answer that the purpose of the -e flag is to tell sed to interpret the subsequent string as a command (or a collection of commands separated by a newline?). So it looks like the body of extract_initial_comment_block contains 3 separate scripts for sed to interpret, in order. That same StackExchange answer says that {...} are used to group commands together, but I'm not sure if that's what is happening in this regex (these regexes?).
As near as I can tell, there are 3 scripts being fed to sed here:
/^#/ !{
q
}
s/^#$/# /
/^# / {
s/^# //
p
}
However, even within each of these scripts, there are patterns being used (such as ^# and !{ q }) that I'm not able to identify, even after availing myself of resources like The Linux Data Project. It seems like there are a lot of moving pieces, and I'm not sure how each script is being composed into a finished product.
I've tried to walk through my thought process in as clear a manner as I can. Is my train of thought correct so far? If it's not, where did I veer off-course? If it is, how can I deduce the meaning of each command that's passed to sed?