I guess I found the reason why.
If I put some blank after the filename, a filename with trailing blanks is searched. I can reproduce the problem this way:
Sources:
cat q.dat
Q
Not q
And Q again
And again not
cat kuh.dat
Die dumme
Kuh
Working example with filename 'kuh.dat':
sed '/Q/{
s/Q//g
r kuh.dat
}' q.dat
Die dumme
Kuh
Not q
And again
Die dumme
Kuh
And again not
Now the failing example, with 'kuh.dat '.
sed '/Q/{
s/Q//g
r kuh.dat
}' q.dat
Not q
And again
And again not
Since the filename isn't quoted, it is a great surprise for me, that the blank at the filename-end is recognized. And it isn't visible in the shell, so I searched for a long time without success, where the difference between the two examples is.
Strictly speaking, the POSIX specification for sed
requires a newline after a\
:
[1addr]a\
text
Write text to standard output as described previously.
This makes writing one-liners a bit of a pain, which is probably the reason for the following GNU extension to the a
, i
, and c
commands:
As a GNU extension, if between the a
and the newline there is other than a whitespace-\
sequence, then the text of this line, starting at the first non-whitespace character after the a
, is taken as the first line of the text block. (This enables a simplification in scripting a one-line add.) This extension also works with the i
and c
commands.
Thus, to be portable with your sed
syntax, you will need to include a newline after the a\
somehow. The easiest way is to just insert a quoted newline:
$ sed -e 'a\
> text'
(where $
and >
are shell prompts). If you find that a pain, bash
[1] has the $' '
quoting syntax for inserting C-style escapes, so just use
sed -e 'a\'$'\n''text'
[1] and mksh (r39b+) and some non-bash bourne shells (e.g., /bin/sh in FreeBSD 9+)
Best Answer
To edit file in-place with OSX sed, you need to set empty extension:
And you need a literal newline after
i\
. This is specified by POSIX sed.Only GNU sed allows text to be inserted on the same line with command.
sed
can also works with multiple files at once, so you can use-exec command {} +
form: