sed
Stream editor for filtering and transforming text
By CMD Script Team · 3 min read · Last updated
sed [OPTIONS] 'SCRIPT' [FILE...]Options
| Flag | Description |
|---|---|
-i | Edit files in place (GNU: -i takes an optional suffix, e.g. -i.bak) |
-n | Suppress automatic printing of the pattern space; use with the p command |
-e | Add a script to the commands to be executed, allowing multiple -e expressions |
-f | Read a sed script from a file instead of the command line |
-E | Use extended regular expressions (same as -r on GNU sed) |
-r | Use extended regular expressions (GNU-specific alias for -E) |
g | Substitution flag: replace all matches on a line, not just the first |
Distribution compatibility
- Ubuntu
- Debian
- Fedora
- Arch
- macOS (BSD sed, -i requires an explicit backup suffix argument)
What it does
sed (stream editor) reads input line by line into a "pattern space," applies a script
of editing commands to each line, and writes the result to standard output. It's built
for non-interactive text transformation — substituting text, deleting lines, printing
ranges — inside scripts and pipelines, without opening a full editor. The most common use
is the substitute command, s/pattern/replacement/, but sed also supports deletion,
insertion, and line-range selection.
Beginner examples
sed 's/foo/bar/' file.txt— replace the first "foo" on each line with "bar"sed 's/foo/bar/g' file.txt— replace every "foo" on each linesed -n '5p' file.txt— print only line 5sed '/error/d' file.txt— remove every line containing "error"
sed 's/localhost/127.0.0.1/' hosts.conf
Advanced examples
- Edit a file in place with a backup:
sed -i.bak 's/DEBUG/INFO/g' app.conf - Print a range of lines like a lightweight
head/tail:sed -n '10,20p' access.log - Chain multiple edits with
-e:sed -e 's/foo/bar/' -e 's/baz/qux/' file.txt - Use extended regex for grouping and alternation:
sed -E 's/(GET|POST) /\1: /' access.log - Insert a line before every match:
sed '/^\[section\]/i\# generated by config tool' file.conf
sed -n '/^Error/,/^$/p' build.log
Common mistakes
- Forgetting the
gflag and being surprised that only the first match per line changed. - Using
sed -ion macOS without an argument and gettingsed: 1: "file.txt": extra characters at the end of s command— BSDsedneedssed -i '' '...'orsed -i.bak '...'. - Not escaping
/inside a pattern or replacement, e.g. matching a path — switch the delimiter instead:sed 's#/usr/local#/opt#'. - Assuming
sededits the file directly by default; without-iit only writes the transformed output to stdout, leaving the original file untouched.
Tips
- Change the delimiter (
s#pattern#replacement#) when your pattern or replacement contains slashes, to avoid a wall of backslash escapes. - Use
&in the replacement to refer to the whole matched text:sed 's/error/[&]/'wraps every match in brackets. - Combine
-nwithpto usesedas a precise line-range printer instead ofhead -n X | tail -n Y.
Best practices
- Always test a
sedsubstitution without-ifirst (or use-i.bak) so you can review the diff before overwriting a file you can't easily recover. - Prefer
-E/-rfor anything beyond a trivial substitution — basic regex escaping (\(,\|,\+) gets unreadable fast. - In portable scripts targeting both GNU and BSD sed, avoid
-ientirely where possible; write to a temp file andmvit into place instead.
Try it yourself
A simulated shell with a sample home directory — experiment freely, nothing leaves your browser. Type help to list supported commands.
Real-world use cases
- Bulk-replacing a hostname or port across many config files during a migration:
sed -i 's/old-host/new-host/g' *.conf. - Stripping comments and blank lines from a config before validating it:
sed '/^\s*#/d;/^\s*$/d' nginx.conf. - Extracting a block of log output between two markers for a bug report:
sed -n '/BEGIN TRACE/,/END TRACE/p' app.log.
Common interview questions
- What's the difference between
sed 's/a/b/'andsed 's/a/b/g'? Withoutg, only the first match per line is replaced;greplaces every match on the line. - How do you use
sedto print a range of lines from a file?sed -n '10,20p' file—-nsuppresses default printing, and10,20pprints only lines 10 through 20. - Why does
sed -ibehave differently on macOS than on Linux? macOS ships BSDsed, which requires an explicit (possibly empty) backup-suffix argument after-i, while GNUsedon Linux treats the suffix as optional and directly attached to-i.
Frequently Asked Questions
Why does sed -i fail or create a weird backup file on macOS?
macOS ships BSD sed, which requires an explicit argument to -i even if you don't want a backup — use sed -i '' 's/foo/bar/' file. GNU sed on Linux treats -i as taking an optional suffix with no space, so sed -i.bak works but sed -i '' would be interpreted differently. This is the single most common sed portability trap.
How do I replace all occurrences on a line, not just the first?
Add the g flag to the substitution: sed 's/foo/bar/g'. Without g, sed only replaces the first match per line.
How do I delete lines matching a pattern?
Use sed '/pattern/d' file to delete every line matching pattern, or sed '2,4d' file to delete lines 2 through 4 by number.
How do I use sed like grep to print only matching lines?
Combine -n with the p command: sed -n '/pattern/p' file. This suppresses the default auto-print and only prints lines where the pattern matches and the p command runs.
Cheat sheet
Download a quick-reference cheat sheet for sed.