How do I insert text to the 1st line of a file using sed?

Suppose you have a file like this:

one
two

Then to append to the first line:

$ sed '1 s_$_/etc/example/live/example.com/fullchain.pem;_' file
one/etc/example/live/example.com/fullchain.pem;
two

To insert before the first line:

$ sed '1 i /etc/example/live/example.com/fullchain.pem;' file
/etc/example/live/example.com/fullchain.pem;
one
two

Or, to append after the first line:

$ sed '1 a /etc/example/live/example.com/fullchain.pem;' file
one
/etc/example/live/example.com/fullchain.pem;
two

Note the number 1 in those sed expressions - that's called the address in sed terminology. It tells you on which line the command that follows is to operate.

If your file doesn't contain the line you're addressing, the sed command won't get executed. That's why you can't insert/append on line 1, if your file is empty.

Instead of using stream editor, to append (to empty files), just use a shell redirection >>:

echo "content" >> file

Your problem stems from the fact that sed cannot locate the line you're telling it to write at, for example:

touch test
sed -i -e '1i/etc/example/live/example.com/fullchain.pem;\' test

attempts to write to insert at the line 1 of test, but that line doesn't exist at this point. If you've created your file as:

echo -en "\n" > test
sed -i '1i/etc/example/live/example.com/fullchain.pem;\' test

it would not complain, but you'd be having an extra line. Similarly, when you call:

sed -i "2i ssl_certificate_key /etc/example/live/example.com/privkey.pem;"

you're telling sed to insert the following data at the line 2 which doesn't exist at that point so sed doesn't get to edit the file.

So, for the initial line or the last line in the file, you should not use sed because simple > and >> stream redirects are more than enough.


Your command will work if you make sure the input file has at least one line:

[ "$(wc -l < test)" -gt 0 ] || printf '\n' >> test
sed -i -e '1 i/etc/example/live/example.com/fullchain.pem;\' test