once more

I was thinking about my last entry and perhaps this one should have come first to make thing clearer. I was trying to show the use of sed for solving a problem. I wanted an example that was complex but still understandable. I was looking for a way to show how to explain the use of pattern and hold buffers in sed. I don't think that's what I got.

The pattern buffer contains the current line. It's what the "s" command performs its replacements to. The hold buffer is another buffer you can use. There are 5 commands (g G h H x) that move thing to and from the hold buffer. You can choose between appending to a buffer or overwriting the buffer. H appends the pattern buffer to the hold buffer, h overwrites the hold buffer with the pattern buffer, G appends the hold buffer to the pattern buffer, and g overwrites the pattern buffer with the hold buffer. x exchanges the hold and pattern buffers

Here is a simplified version so you can see what I'm talking about. It takes the input and treats every "a" line like a menu command, every "b" line like an executable, and every "c" line like an end. For every "a" there is a "c" to end it. My plan is to treat the hold buffer like a stack. Every time I see an "a" I push it onto the stack. Everytime I see a "b" I push it onto the stack. If I see a "c" I want to match the end of the hold buffer (my stack) from the last "a" to the end, print that, and then remove that matched string from the hold buffer.

Here is my input file, one item per line since I'm not trying to show matching and sustituting.

a
b
a
b
b
c
b
c

Here is the sed script. You can see that the first two commands look for a match and if they find one put the item onto the end of the hold buffer with the H. The third command overwrites the pattern space with the hold space (because we didn't need the "c" end statement). Then it matches for an s with as many characters as possible which are not s and prints it. That next g grabs the hold space again and overwrites the new pattern we just made. This time, rather than keeping the back of the straing, though, we want the front, and we tack on an extra d to show that there is a submenu call. the h replaces the hold buffer with the pattern buffer, and the last "c" command replaces the pattern with whatever text you wand and prints it.

################################################
# if the current pattern matches "a", append the
# current pattern buffer to the hold buffer

/a/H

# if the current pattern matches "b", append the
# current pattern buffer to the hold buffer

/b/H

# if the current pattern matches "c", do the
# block of commands between the { }
/c/{
g
s/\(.*\)\(a[^a]*\)/\2/p
g
s/\(.*\)\(a[^a]*\)/\1d/
h
c END MENU\