1

Shouldn't the second 'test' line also get replaced? How would I have to write the command to replace all 'test'?

$ sed 's/test/toast/' texttest.txt 
toast file test file hahahaha 1
toast file test file hahahaha 2
1

2 Answers 2

7

Ok, got it …

g Make the substitution for all non-overlapping matches of the regular expression, not just the first one.

$ sed 's/test/toast/g' texttest.txt 
toast file toast file hahahaha 1
toast file toast file hahahaha 2
2
  • 1
    I believe g means global. Nov 28, 2020 at 8:18
  • That's a very silly default. Now I'm wondering how many instances that I wanted to replace I've inadvertently left lying around in files when I used sed. Nov 29, 2020 at 0:11
1

As you've already found out, s/test/toast/ will only replace the first occurrence of "test" on each line with "toast". To make sed replace all non-overlapping occurrences of "test" with "toast", you need to append the global replacement flag g to the replacement command, as in:

$ echo 'This test is a test.' | sed 's/test/toast/g'
This toast is a toast.

Note that the g flag only handles non-overlapping replacements, and will e.g. turn "testest" into "toastest", not into "toastoast":

$ echo 'This test is the testest test.' | sed 's/test/toast/g'
This toast is the toastest toast.

If you do want overlapping replacements, this can be worked around using a loop:

$ echo 'This test is the testest test.' | sed ':loop; s/test/toast/; t loop'
This toast is the toastoast toast.

Ps. Using ; as a command separator, as above, is a GNU sed feature. For BSD sed (as found e.g. on MacOS), you need to use literal newlines or multiple -e arguments instead:

$ echo 'This test is the testest test.' | sed ':loop
s/test/toast/
t loop'
This toast is the toastoast toast.

$ echo 'This test is the testest test.' | sed $':loop\n s/test/toast/\n t loop'
This toast is the toastoast toast.

$ echo 'This test is the testest test.' | sed -e ':loop' -e 's/test/toast/' -e 't loop'   
This toast is the toastoast toast.

(All of these will also work on GNU sed. The second version, with $'', relies on a feature of some shells, such as bash and zsh, and may require quoting any backslashes appearing in your sed code itself.)

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