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.

  • Jon

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

  • Christian

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

  • Bovine

    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

    • Joe

      Thanks for clarifying that!

  • Michael

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

  • Andris

    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.

  • Uncle B

    Thanks for that. I was struggling!

  • hakova

    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

    • Jon V

      It’s working as expected. -i implies that you will be editing a file in place, not the stdin stream that you’re referring. The right answer is:

      sed -i tmp -e ‘s/apples/oranges/’ test.txt

  • Callum

    $ sed –version
    GNU sed version 4.2.1

    $ sed -i ‘.orig’ -e ‘s/oranges/apples/’ file
    Returns a misleading error about not being able to read .orig, turns out the space between the -i and the ‘.orig’ throws it off. Instead, this works as expected:
    $ sed -i’.orig’ -e ‘s/oranges/apples/’ file

    Thanks for the helpful article, congrats on being the first result for “sed in place” on Scroogle. :-)

  • Stealthcupcake

    Why don’t they just fix this? It is stupid to have an “edit in place” flag that doesn’t work unless you do some undocumented obscure thing that wastes a bunch of time to find on the internet.

    • RTFM

      Lol, “some undocumented obscure thing” that’s in the manpage. Uhuh.

    • V̶e̶r̶i̶f̶i̶e̶d อ_อ

      Maybe you can commit a patch! :D

  • Guest

    Just a hint: If sed is used on symlinks, the link is destroyed and replaced by a copy of the link target.

  • me

    Thanks! That was driving me nuts. I’m running MacOSX.

    sed –version
    sed: illegal option — -
    usage: sed script [-Ealn] [-i extension] [file ...]
    sed [-Ealn] [-i extension] [-e script] … [-f script_file] … [file ...]

  • Nathan Long

    It’s not dangerous at all if the files you’re working with are under version control. With git, starting from a clean commit, a simple `git diff` lets you verify that you’ve changed what you think you have.

    Thanks for the post! You saved me some time.

  • Jason

    Thanks, saved me a lot of frustration when I trying to run a script on os x that worked fine elsewhere!

  • Zachary Burke

    Thank you for this post, 4 years later I’m blown away that my mac is using utilities written in 1977 that have apparently never been updated.

  • nathan_f77

    Thanks! I learned sed on Ubuntu, and ran into this issue after switching to OS X.