[Toybox] sed -e '$a\'

Rob Landley rob at landley.net
Wed Mar 23 13:26:42 PDT 2016


On Wed, Mar 23, 2016 at 1:30 PM, Andy Chu <andychup at gmail.com> wrote:
>> No idea whether that is a valid complaint. coreutils accepts it and
>> treats it as "add a newline (but only if needed) and then do nothing".
>>
>> Debian's update-ca-certificates script uses that to conditionally add a
>> newline after a file which may or may not end with a newline:
>> http://anonscm.debian.org/cgit/collab-maint/ca-certificates.git/tree/sbin/update-ca-certificates#n100
>>
>>   # Add trailing newline to certificate, if it is missing (#635570)
>>   sed -e '$a\' "$CERT" >> "$TEMPBUNDLE"
>
> Not that this matters, but
>
> 1) Why wouldn't they just add a newline unconditionally?  Generally
> textual formats don't care how many blank lines you have.

No idea. The bug report
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=635570 doesn't say
either.

> 2) It does indeed seem undocumented -- I can't find any mention of
> this (unintuitive) behavior in the GNU sed manual or FAQ:

The _fun_ part is that this is doubly nonstandard, because the logic
I've used so far is if the line of input didn't have a newline, we
don't add one _until_ we output another line after it, in which case
we backfill the missing newline.

Exampe:

$ sed -n 'p' <(echo -n hello) <(echo -n there)
hello
there

"hello" has a newline but "there" doesn't, even though neither did on
input. If you insert a /h/ on the p you get just hello (with no
newline), if you insert a /t/ before the p you get just there (with no
newline before it). Not it can't make the decisions about which lines
to show in those cases until it reads further input, I.E. it has to
amend previous decisions about whether or not to show a newline based
on new input. (And you could stick arbitrary "boom" lines in the
second file before "there", so reading one line ahead tells you
nothing.)

(Do I have those four tests in the test suite yet? I know I checked it
by hand so maybe?)

But what THIS is doing is fiddly:

$ echo -ne "one\ntwo\nthree" | sed 'a\'
one
two
three

It's NOT adding a blank line between each line of input, it _only_
affects the decision about whether or not there's a newline on the
last line. Which means:

$ sed -n 'p;a\' <(echo -n one) <(echo -n two)
one
two

And yes there's a newline on two, but only ONE newline after one.

The <strike>Aristocrats</strike>FSF!

Did you know Debian is the FSF's official distribution, entirely due
to Bruce Fscking Perens? (It was the single major accomplishment of
his tenure as project maintainer.)

Right, how about:

$ sed -n 'p;ablah' <(echo -n one) <(echo -n two)
one
blah
two
blah

$ sed -n 'p;ablah\' <(echo -n one) <(echo -n two)
one
blah
two
blah

$ sed -n 'p;a' <(echo -n one) <(echo -n two)sed: -e expression #1,
char 3: expected \ after `a', `c' or `i'

Oh THANK YOU SO VERY MUCH. And the horse you rode in on, and your
little dog too.

Rob

 1458764802.0


More information about the Toybox mailing list