Using shell parameter expansion

Syntax: ${VARNAME//FIND/REPLACE}. The // is necessary for global replacement.

$ x=foo_bar_baz_buzz

$ echo ${x//_/-}
foo-bar-baz-buzz

$ echo ${x/_/-}
foo-bar_bazz_buzz

Using sed and a regex pattern

Regex substitution is used in this guide. Test your pattern at regex101.com.

Syntax: s/FIND/REPLACE/g.

The g is for global and is more useful for files and multi-line strings than for one-line strings.

Example:

s/foo/bar/g

Use g for global. Add I after g for case insensitive flag.

Some characters must be escaped such as with backslash.

Replace word

Using a string.

$ echo 'football' | sed 's/foo/bar/g'
bartball
$ echo 'football' | sed 's/foo/bar/g'
tball

Using a variable.

$ x='football'
$ echo $x | sed 's/foo/bar/g'
bartball

Replace newline character

Given text:

$ echo 'Hello\nworld'
Hello
world

Note that those also remove a trailing newline.

Note you don’t need to escape \n as \\n.

sed

Using sed. This doesn’t work on the macOS sed though.

$ echo 'Hello\nworld' | sed 's/\n/ /'
Hello world

tr

Using tr.

$ echo 'Hello\nworld' | tr '\n' ' '
Hello world

Replace character with a newline character

Use \ followed by pressing enter. Using \n doesn’t seem to work here.

sed

$ echo 'Hello,World' | sed 's/,/\
/g'
Hello
World

tr

Both of these work.

$ echo "Hello:world" | tr ':' '\n'
Hello
world
$ echo "Hello:world" | tr ':' '
'
Hello
world

Make sure that the 2nd argument for tr is ' followed by enter - if you press space and then enter then it doesn’t work.

Replace inline in file with backup flag

The default use of sed will just print, without saving to a file.

sed 's/foo/bar/g' file.txt

So use the inline flag to update the file.

# Linux
sed -i'' 's/foo/bar/g' file.txt
# macOS
sed -i '' 's/foo/bar/g' file.txt

See more info in my sed guide.

Replace word in file

Replace foo with bar in file.txt and print to the console.

sed -i 's/foo/bar/g' file.txt

From tutorial

Replace multiple words in a file

Use multiple replacements in one command

Separate with semicolon

sed -i 's/foo/bar/g; s/fizz/buzz/g' file.txt

Separate with newline

sed -i 's/foo/bar/g
s/fizz/buzz/g
' file.txt

Advanced

For more control, you can use you can use an intermediate term. Like the arbitrary ~~ below.

Here we rename foo to bar but preserve instances of food.

sed -i 's/food/~~/g; s/foo/bar/g; s/~~/food/g' file.txt

source

Note there may be a cleaner way to do this, such a with regex in the console or your IDE. Maybe with grep or find.

Replace a word in multiple files

Replace foo with bar in all files in a directory.

sed -i 's/foo/bar/g' *

sed -i 's/foo/bar/g' foo/*

I don’t think it goes into a directory though and it gives errors on processing directory. So that is why using find and setting type as file as later in this guide is useful.

Delete lines

Delete an entire line matching pattern.

sed

$ sed -i '' '/foo/d' file.txt

Use the reverse match.

$ sed -i '' -n '/foo/!p' file.txt

tr

Using --delete flag.

$ tr -d 'foo' < file.txt

awk

Use the reverse match.

Note that > will start overwriting immediately so you need a temp file.

$ awk '!/foo/' file.txt > temp && mv temp file.txt

grep

Use the reverse match.

$ grep -v "foo" file.txt > temp && mv temp file.txt

Replace and output a new file

$ sed 's/spam/eggs/g' foo.html > bar.html

Combine sed and find

Use find to find files and replace in-line, while the sed part is your transformation.

This is useful to apply to files only since sed will give an error on in-place replacements against directories. Also, find is suited for finding files nested in directories.

General:

$ find . -type f -exec sed -i 'PATTERN' {} \;

e.g.

$ find . -type f -exec sed -i 's/foo/bar/g' {} \;

Replace tabs with 2 spaces in a directory:

$ find . -type f -exec sed -i 's/\t/  /g' {} \;

From StackOverflow.

You can narrow down the name. Here is a glob. Make sure to use a star that is quoted. Also the star glob will not match hidden directories - this will help you avoid accidentally updating and breaking .git.

$ find . -type f -name '*' -exec 'sed -i .bak -e "PATTERN" {} +'
$ find . -exec sed -i '' -e 'PATTERN' {} \;
 -e command
             Append the editing commands specified by the command argument to the list of commands.

Or reverse the order so find is used by sed. I found this easier than the syntax above which I copied but kept getting errors on.

$ sed -i 's/foo/bar/g' $(find . -type f)

Install sed

If you are used to the GNU (Linux) sed, you can set it up on macOS too.

StackOverflow

$ brew install gnu-sed

Add to .bashrc or .zshrc to make is accesible.

export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"