There are a few ways to go about this w/
sed. One way is a delayed read as is recommended in the accepted answer. It could also be written like:
sed -e '$!N;P;/\nPointer/r file1' -e D file2
...with a little explicit look-ahead instead of the look-behind implemented elsewhere with the hold buffer. That will inevitably have the same problem with the last line that @don_crissti notes, though, because
N does increment the line cycle and the
read command is applied by line number.
You can get around it:
echo | sed -e '$d;N;P;/\nPointer/r file1' -e D file2 -
seds will interpret the
- to mean standard input, but many do. (POSIX says
sed should support
- to mean standard-in if the implementer wants
- to mean standard-in???)
Another way is to handle the appended content in order. There is another command that schedules output in the same way
read does, and
sed will apply it and
read in the order they're scripted. It's a little more involved though - it entails using one
Pointer match to the output of another
sed in its script.
sed ' /Pointer/!d #only operate on first match
s/^$&\./*/\\&/g;H #escape all metachars, Hold
s|.*|/&/!p;//!d|p;g #print commands, exchange
s|.|r file1&a\\&|;q' file2| #more commands, quit
sed -nf - file2 #same input file
So basically the first
sed writes the second
sed a script, which the second
sed reads on standard-input (maybe...) and applies in turn. The first
sed only works on the first match for
Pointer found, and afterward
quits input. Its job is to...
- Make sure that all pattern chars are safely backslash-escaped because the second
sed is going to need to interpret every bit it reads literally to get it right. Once that's done, put a copy in
- Tell the second
print every input line
/&/ one we just pattern-safed; and then to
delete all of the same.
print the commands at the second
sed, then e
hold and pattern buffers to work on our saved copy.
- The only char we work with here is a
sed will have prepended one when we
Held the line before. So we insert the command
r file1 and follow it with our
\newline then the command
append followed also by a
\newline. All of the rest of our
Held line follows that last
The script that the first writes looks something like this:
Basically the second
sed will print every line but the one the first
sed sets it up to
append. For that particular line two delayed writes to standard-out are scheduled - the first is the
file1 and the second is a copy of the line we want after it. The first
sed's doctoring isn't even necessary in this case (see? no backslashes) but it is important to safely escape in the way I do here whenever a pattern match is repurposed as input.
Anyway, so... there are a few ways.