40

I am trying to replace multiple words in a file by using

sed -i #expression1 #expression2

file

Something  123 item1
Something  456 item2
Something  768 item3
Something  353 item4

Output (Desired)

anything  123 stuff1
anything  456 stuff2
anything  768 stuff3
anything  353 stuff4

Try-outs

I can get the following output by using sed -i two times.

 sed -i 's/Some/any/g' file
 sed -i 's/item/stuff/g' file

Can I have any possible way of making this as a single in-place command like

sed -i 's/Some/any/g' -i 's/item/stuff/g' file

When I tried the above code it takes s/item/stuff/g as a file and tries working on it.

1
  • 1
    If your files are similar to the example above (i.e they follow the same pattern) you can do it with a single substitution: sed - i 's/Some\(.*\)item/any\1stuff/' file Commented Dec 21, 2014 at 23:44

4 Answers 4

48

Depending on the version of sed on your system you may be able to do

sed -i 's/Some/any/; s/item/stuff/' file

You don't need the g after the final slash in the s command here, since you're only doing one replacement per line.

Alternatively:

sed -i -e 's/Some/any/' -e 's/item/stuff/' file

Or:

sed -i '
  s/Some/any/
  s/item/stuff/' file

The -i option (a GNU extension now supported by a few other implementations though some need -i '' instead) tells sed to edit files in place; if there are characters immediately after the -i then sed makes a backup of the original file and uses those characters as the backup file's extension. Eg,

sed -i.bak 's/Some/any/; s/item/stuff/' file

or

sed -i'.bak' 's/Some/any/; s/item/stuff/' file

will modify file, saving the original to file.bak.

Of course, on a Unix (or Unix-like) system, we normally use '~' rather than '.bak', so

sed -i~ 's/Some/any/;s/item/stuff/' file
5
  • 2
    Note that you're describing the GNU variant. The BSD variant (as in FreeBSD or OS/X) requires an argument for -i. So sed -i '' 's/a/b/;s/c/d/' file or sed -i .back 's/a/b/;s/c/d/' or sed -i.back 's/a/b/;s/c/d/' there. Other sed implementations generally don't support -i. Commented Dec 17, 2014 at 10:06
  • Thanks @StéphaneChazelas for clarifying that. And I guess I should have been more explicit in saying that in GNU sed there cannot be a space between the -i and the extension.
    – PM 2Ring
    Commented Dec 17, 2014 at 11:30
  • sed -i 's/$username = "root"/$username = "newuser"/; s/$password = "password"/$password = "passwd"/; s/$dbname="handicraftstore"/$dbname="handicraft"' Web/database.php results sed: -e expression #1, char 141: unterminated s' command`
    – alhelal
    Commented May 1, 2018 at 6:56
  • @alhelal Sorry, comments are not the proper place to ask questions. But anyway, your last s command is missing its final /.
    – PM 2Ring
    Commented May 1, 2018 at 8:01
  • @PM2Ring as I didn't notice that I guessed it is related your solution. However, thank you.
    – alhelal
    Commented May 1, 2018 at 8:14
10

You can chain sed expressions together with ";"

%sed -i 's/Some/any/g;s/item/stuff/g' file1
%cat file1
anything  123 stuff1
anything  456 stuff2
anything  768 stuff3
anything  353 stuff4
6

Multiple expression using multiple -e options:

sed -i.bk -e 's/Some/any/g' -e 's/item/stuff/g' file

or you can use just one:

sed -i.bk -e 's/Some/any/g;s/item/stuff/g' file

You should give an extension for backup file, since when some implementation of sed, like OSX sed does not work with empty extension (You must use sed -i '' to override the original files).

1

You can use Vim in Ex mode:

ex -sc '%s/Some/any/|%s/item/stuff/|x' file
  1. % select all lines

  2. s substitute

  3. x save and close

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .