34

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 Dec 21, 2014 at 23:44

4 Answers 4

42

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. 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
    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
    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
    May 1, 2018 at 8:01
  • @PM2Ring as I didn't notice that I guessed it is related your solution. However, thank you.
    – alhelal
    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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.