Move the faculty lines around so that people in Torgersen Hall are listed
on consecutive lines, after all the people in McBryde Hall.
This is a bit tricky. We can reason in the following way: At any
point in time, let us
have the hold buffer have the lines (those
read so far) in the correct order. So, all these lines will
have the McBryde Hall lines before the Torgersen Hall lines. Then we
read in the next line. If the line contains 'McBryde Hall', we add it
in the beginning of the buffer. If the line contains 'Torgersen Hall',
we add it at the end of the buffer. So far so good. But how do we
stop this process? We have to somehow print the lines at the end
of the day. Here's a solution using branches and yet another command
called t. t is like b, in that it is useful
for branching. But while b branches unconditionally,
t branches only if there has been a previously successful
substitution on the line that was read. See how we use it
below (it is only long because of the comments):
1{ # the story begins with the first line
h # save that line in the buffer, because we dont care
# if it has Torgersen Hall or McBryde Hall,
# the iteration starts here!
d # delete the line from the current buffer
b # branch out, i.e., stop doing any more tests,
# and goto end of commands
}
${ # we have just read the last line
# so far the hold buffer contains what we want.
# the question is whether we should put this last
# line at the beginning or end.
s/\(.*\) Torgersen Hall \(.*\)/\1 Torgy Hall \2/
# substitute Torgersen Hall for Torgy Hall. This
# is an indirect way of seeing if there was a Torgersen
# Hall in the line.
t777 # if there was a substitution, branch to line numbered 777
G # there was no substitution, that is why we are here.
# so that means this line contains McBryde Hall.
# we use a G to append the hold buffer after the current line.
p # print it...
b # and exit!
:777 s/\(.*\) Torgy Hall \(.*\)/\1 Torgersen Hall \2/
# we reach the 777 line because there was a Torgersen Hall.
# replace the Torgy with Torgersen.
H # do a H, instead of a G, because we want the Torgersen Halls
# to goto the end of the lines.
x # exchange the hold space and the current space
p # print the current space!
}
/Torgersen Hall/{
H # append this line to hold space, because we want the Torgersen Halls
# to goto the end of the lines.
d # delete the current line.
}
/McBryde Hall/{
G # append hold space to given line, because we want the McBryde Halls
# to come at the beginning.
h # move it to hold, for safe storage.
d # and delete.
}
When we apply this script on the previous file, we get:
Name: Dennis Kafura Office: 660 McBryde Hall Course: CS 5204
Name: Manuel Perez Office: 638 McBryde Hall Course: CS 1706
Name: Chris North Office: 634 McBryde Hall Course: CS 5764
Name: Lenwood S. Heath Office: 2160J Torgersen Hall Course: CS 4124
Name: Godmar Back Office: 2160A Torgersen Hall Course: CS 5204
Name: Naren Ramakrishnan Office: 2160L Torgersen Hall Course: CS 2204
Name: Liqing Zhang Office: 2160K Torgersen Hall Course: CS 5045
Note that the 'McBryde Hall's are printed in the reverse
order in which they are encountered, because we keep adding them
in the front. Whereas the 'Torgersen Hall's are printed in the
order in which we encounter them, because we add them at the
end.