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.
Print lines
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' {} +
Print without modifying
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 |
|
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.