busybox sed, 'r' command
Michael Conrad
mconrad at intellitree.com
Wed Mar 23 16:25:03 UTC 2016
On 3/23/2016 12:12 PM, Ralf Friedl wrote:
> Cristian Ionescu-Idbohrn wrote:
>> sed (GNU sed) 4.2.2 can do this:
>>
>> $ printf 'foo
>> bar
>> baz' | sed r -
>> foo
>> bar
>> baz
>>
>> or, after storing the text in a file:
>>
>> $ printf 'foo
>> bar
>> baz' >/tmp/bar
>>
>> $ sed r /tmp/bar
>> foo
>> bar
>> baz
>>
>> But busybox sed can't:
>>
>> $ printf 'foo
>> bar
>> baz' | busybox sed r -
>> sed: empty filename
>>
>> $ busybox sed r /tmp/bar
>> sed: empty filename
>>
>> $ printf '' | busybox sed 'r /tmp/bar'
>> <no output, although /tmp/bar size is 11 bytes>
>>
>> $ busybox sed 'r /tmp/bar'
>> <waiting for stdin; ^D; no output>
>>
>> The 'r' command is documented by GNU sed as a GNU extension. Still,
>> busybox sed documents the 'r' command as supported:
>>
>> r [address]r file
>> Read contents of file and append after the contents of the
>> pattern space. Exactly one space must be put between r and
>> the
>> filename.
>>
>> Am I misinterpreting the documentation?
> From the documentation:
> > The full format for invoking `sed' is:
> > sed OPTIONS... [SCRIPT] [INPUTFILE...]
> So in your example you invoce sed with the script "r" and the input
> file "-" or "/tmp/bar". The content is not printed because it is the
> argument to the "r" command, but because it is the main input file to
> sed. You can avoid that by using quotes around the command and the
> file name, or by omitting the space between the command and the filename.
> You should also try the last two examples, where you invoke busybox
> sed with quotes, with GNU sed. The behaviour is the same.
>
> You should note that in your example when reading from a file, sed
> didn't read from stdin, at least you don't mention it, although your
> interpretation would mean that the filename is the argument to the "r"
> command, therefor no argument is given to sed, and sed should read stdin.
>
> You should also not that invoking the "r" command with the filename
> causes the content of this file to be inserted after every line. When
> reading from a pipe, the pipe is empty after the first line.
>
> My documentation to GNU sed 4.2.2 says:
> > `r FILENAME'
> > As a GNU extension, this command accepts two addresses.
> >
> > Queue the contents of FILENAME to be read and inserted into the
> > output stream at the end of the current cycle, or when the next
> > input line is read. Note that if FILENAME cannot be read, it is
> > treated as if it were an empty file, without any error indication.
> >
> > As a GNU `sed' extension, the special value `/dev/stdin' is
> > supported for the file name, which reads the contents of the
> > standard input.
>
> So the main difference seems to be that GNU sed doesn't give an error
> message if the file can't be read. I'm not sure why that would be a
> good idea.
> Also not that there is no mention of using "r -" for stdin, instead
> /dev/stdin is mentioned.
>
> On the other hand, I don't know why busybox sed needs exactly one
> space between command and filename. GNU sed works with zero or more
> spaces.
It looks to me that what actually happens when running "sed r" is that
it appends *no lines* to the end of each line read from stdin.
$ printf 'foo
bar
baz' | sed
Does not add a final newline
$ printf 'foo
bar
baz' | sed r
Does add a final newline
$ printf 'foo
bar
baz' | sed 'r /dev/null'
Does add a final newline
echo "blah" > -
$ printf 'foo
bar
baz' | sed 'r -'
results in
foo
blah
bar
blah
baz
blah
So it is not a special case for the filename.
I personally don't see much value in preserving the behavior of
appending nothing for a file which doesn't exist. Tools should give
errors if they can't do what you ask them to.
-Mike C.
More information about the busybox
mailing list