Match the Terminal Condition Twice
Regardless of the language, the most common technique for line-oriented processing is to print lines within a given range and then use a second command to exit the loop when your terminal condition is reached. This will be true for common patterns in sed, awk, ruby, and perl, although there are certainly other techniques that can be performed using multi-line matches (not supported in sed without using the hold space). For example, you might use a non-greedy, multi-line regular expression pattern such as /^abc\n.*?\nxyz$/m
.
To illustrate the line-oriented approach you want a little more verbosely, consider this Ruby one-liner where $_
holds the current input line. From the shell:
$ ruby -ne 'puts $_ if /^abc$/ .. /^xyz$/; exit if /^xyz/' filename
abc
123
xyz
The equivalent in sed is:
$ sed -n '/^abc$/,/^xyz$/p; /^xyz$/q' filename
abc
123
xyz
All you were missing was a quit or exit command attached to the second match against the first instance of xyz
.