Joe Maller.com

Quick note about sed’s edit in place option

From the sed manpage:

-i extension
   Edit files in-place, saving backups with the specified extension.
   If a zero-length extension is given, no backup will be saved.  It
   is not recommended to give a zero-length extension when in-place
   editing files, as you risk corruption or partial content in situ-
   ations where disk space is exhausted, etc.

This doesn’t work:

sed -i -e's/apples/oranges/' file.txt

The key thing here is that the extension after the -i flag is not optional. If you leave it off, sed assumes you’ll be entering it via stdin, which isn’t allowed and yields this error:

sed: -i may not be used with stdin

The solution is to send a zero-length extension like this:

sed -i '' -e's/apples/oranges/' file.txt

Careful with this, it could be really dangerous with poorly crafted commands.


8 Responses to “Quick note about sed’s edit in place option”

  • Thanks for the tip. I was having trouble getting the edit-in-place option to work.

  • Thanks for your excellent tip. Has saved me from weird backup files that caused alot of headaches

  • It seems that some versions of sed require the argument after -i and others do not.

    With GNU sed version 4.1.x, it seems that the -i does not require an argument and specifying an empty argument after it actually fails:

    sed -i ” -e’s/apples/oranges/’ file.txt
    sed: can’t read : No such file or directory

    sed -i -e’s/apples/oranges/’ file.txt
    (works)

    • Thanks for clarifying that!

  • Was recently fiddling and ran into the -i issue… -i ” failed, but -i” worked. Fedora Core 11 x86_64.

  • Thanks Joe – it is a really helpful tip!

    As for me, those versions of sed which require user to specify the argument for the -i option demonstrate the more secure way in processing potentially destructive commands. In other words such versions of sed stimulate user to read the documentation carefully.

  • Thanks for that. I was struggling!

  • Thanks, I was excited to find this, but I couldn’t get -i to work in FreeBSD 8.0 period; that is with or without extension. Always get the same error (‘sed: -i may not be used with stdin’) with all the example lines below:

    sed -i ‘tmp’ -e ‘s/apples/oranges/’ <test.txt
    sed -i '' -e 's/apples/oranges/' <test.txt
    sed -i'' -e 's/apples/oranges/' <test.txt
    sed -i' ' -e 's/apples/oranges/' <test.txt
    and so forth.

    These work:
    sed 's/apples/oranges/' testnew.txt
    sed -e’s/apples/oranges/’ testnew.txt
    sed -e ‘s/apples/oranges/’ testnew.txt

Leave a Reply