Well, let's see...
the b
ranch command:
[2addr]b[label]
Branch to :label. If label is not specified, branch to the end of the script.
the n
ext command:
[2addr]n
If auto-print is not disabled, print the pattern space, then, regardless,
replace the pattern space with the next line of input. If no next line of
input is available, branch to the end of the script.
So the main difference here is:
b
unconditionally branches to the end of script
n
only branches to the end of script if there's no more input
Assuming an input like:
fdue
four
four
fdue
four
and that I wanted to replace f
with t
but only on lines that match four
and on all other lines replace u
with i
. One way to do this is
sed '/four/{s/f/t/;b;};s/u/i/' infile
and the output is, as expected
fdie
tour
tour
fdie
tour
now, let's see what happens when using n
instead of b
:
fdie
tour
foir
fdie
tour
The second line matching four
was edited to foir
instead of tour
for the simple reason n
does not return to the top of the script. Instead, the s
command following the n
processed the line even thought this was not intended. However, on the last line, only the 1st substitution was made so the s
command after the n
was no longer executed.
To sum up, these two commands could be functionally equivalent if:
- the script was processing the last line of input (before executing
n
) or
- the next line pulled in by
n
was not supposed to be edited by the commands that precede n
1 anyway (in other words, the next line was not an address that's associated to b
)
It's true that n
prints the current pattern space and pulls in the next line but b
alone also has the same effect: branching to end of script means auto-printing (unless sed
was invoked with -n
, in which case n
doesn't print either) and then automatically reading in the next line of input. The main difference, as I said, is that n
doesn't jump to end of script (and it doesn't return to top of the script either): sed
simply executes the remaining commands - if any (and if not on the last line).
1
Those commands won't be executed since, as I said, n
doesn't return to the top of the script; also, the remaining commands might edit the line which is something that wasn't supposed to happen.
b
without a label starts next cycle, whilen
reads the next line from the input and keeps going. Compare f.i. the results ofseq 1 5 | sed '/2/ { b; d; }'
andseq 1 5 | sed '/2/ { n; d; }'
. – Satō Katsura Jul 07 '16 at 21:14n
command and Awk'snext
command. I now realized that Awk'snext
command is actually equivalent to the delete command (d
) in Sed. :) – Wildcard Nov 18 '16 at 02:23next
isn't exactly equivalent tosed
'sd
either. A guy named Banach came up with the hierarchy of theories, analogies between theories, and analogies between analogies. He didn't quite get to analogies between apples and orange juice. Now, that would make for an entertaining development. :) – Satō Katsura Nov 18 '16 at 04:43sed
has a pattern space and a hold space, whileawk
has records and the associated bookkeeping. Basic thing to understand about computers and algorithms: data structures always trump behavior. The former are measurables. The latter isn't. – Satō Katsura Nov 18 '16 at 05:27