Basics of sed

sed = stream editor.

It reads text line-by-line, applies commands, and writes the result.

Basic syntax

sed 'command' file

Example:

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

By default, sed does not modify the original file.

sed -n '1p' file.txt

Print line 1.

sed -n '1,5p' file.txt

Print lines 1–5.

sed -n '10,$p' file.txt

Print line 10 through the end.

-n disables automatic printing.

Without -n, p can cause duplicate output:

sed '1p' file.txt

Delete lines

sed '1d' file.txt

Delete line 1.

sed '1,5d' file.txt

Delete lines 1–5.

sed '/foo/d' file.txt

Delete lines containing foo.

sed '/^#/d' file.txt

Delete lines beginning with #.

Substitute text

The most common sed command is s:

sed 's/old/new/' file.txt

Replace the first old on each line.

Replace all occurrences

sed 's/old/new/g' file.txt

g = global replacement on each line.

Case-insensitive replacement

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

i = case-insensitive.

Different delimiters

/ is conventional, but you can use other characters:

sed 's|/old/path|/new/path|g' file.txt

This is useful when replacing paths.

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

Regular expressions

sed 's/[0-9]/X/g' file.txt

Replace every digit.

sed 's/^/# /' file.txt

Add # to the beginning of every line.

sed 's/$/;/' file.txt

Add ; to the end of every line.

sed 's/[[:space:]]\+$//' file.txt

Remove trailing whitespace.

Addressing specific lines

Commands can be restricted to particular lines.

Line number

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

Only replace on line 5.

Range

sed '5,10s/foo/bar/g' file.txt

Replace on lines 5–10.

Pattern

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

Only modify lines containing foo.

Range between patterns

sed '/BEGIN/,/END/d' file.txt

Delete from BEGIN through END.

Multiple commands

Use -e:

sed -e 's/foo/bar/g' -e '/^#/d' file.txt

Or separate commands with ;:

sed 's/foo/bar/g; /^#/d' file.txt

For more complex scripts:

sed -f script.sed file.txt

In-place editing

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

This modifies file.txt.

Create a backup

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

Creates:

file.txt
file.txt.bak

macOS vs Linux

GNU/Linux:

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

macOS:

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

Multiple files

sed -i 's/foo/bar/g' file1.txt file2.txt file3.txt

Using a glob:

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

Using find:

find . -name '*.txt' -exec sed -i 's/foo/bar/g' {} +

A useful pattern:

sed -n 's/foo/bar/p' file.txt

Replace foo with bar and print only lines where a replacement occurred.

Extract lines

sed -n '/BEGIN/,/END/p' file.txt

Print everything from BEGIN through END.

sed -n '/error/p' log.txt

Print lines containing error.

Remove blank lines

sed '/^$/d' file.txt

Remove completely empty lines.

More robust:

sed '/^[[:space:]]*$/d' file.txt

Remove empty or whitespace-only lines.

Comment lines

Add comments:

sed 's/^/# /' file.txt

Remove a leading comment:

sed 's/^# //' file.txt

Capture groups

Use \(...\) with basic regular expressions:

sed 's/\([0-9]\+\)-\([0-9]\+\)/\2-\1/' file.txt

Modern GNU sed can use extended regex with -E:

sed -E 's/([0-9]+)-([0-9]+)/\2-\1/' file.txt

& means “the entire matched text”:

sed 's/foo/[&]/' file.txt
foo bar

becomes:

[foo] bar

sed with pipes

sed works especially well in pipelines:

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

But cat is usually unnecessary:

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

Example:

ps aux | sed -n '1,5p'

Common commands

Command Meaning
s/a/b/ substitute first a with b
s/a/b/g substitute all
d delete
p print
q quit
-n disable automatic printing
-i edit file in place
-E extended regular expressions
-e specify a command
-f read commands from a file

Most useful patterns

# Replace text

sed 's/foo/bar/g' file

# Replace in-place

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

# Print specific lines

sed -n '10,20p' file

# Delete specific lines

sed '10,20d' file

# Delete matching lines

sed '/pattern/d' file

# Print matching lines

sed -n '/pattern/p' file

# Add text to beginning

sed 's/^/prefix/' file

# Add text to end

sed 's/$/suffix/' file

# Remove blank lines

sed '/^$/d' file

# Extract a section

sed -n '/BEGIN/,/END/p' file

# Delete a section

sed '/BEGIN/,/END/d' file

Mental model

Think:

input

sed reads one line

check address/pattern

run command

output modified line

next line

The core things to learn are:

sed
├── addresses → which lines?
├── s → replace text
├── d → delete
├── p → print
├── regex → what to match?
└── -i → modify the file

If you know addresses + regex + s + d + p, you already know most everyday sed.