>_cmd.script

sed

Stream editor for filtering and transforming text

Text Processing

By CMD Script Team · 3 min read · Last updated

SYNTAX
sed [OPTIONS] 'SCRIPT' [FILE...]

Options

Command options and flags
FlagDescription
-iEdit files in place (GNU: -i takes an optional suffix, e.g. -i.bak)
-nSuppress automatic printing of the pattern space; use with the p command
-eAdd a script to the commands to be executed, allowing multiple -e expressions
-fRead a sed script from a file instead of the command line
-EUse extended regular expressions (same as -r on GNU sed)
-rUse extended regular expressions (GNU-specific alias for -E)
gSubstitution 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 line
  • sed -n '5p' file.txt — print only line 5
  • sed '/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 g flag and being surprised that only the first match per line changed.
  • Using sed -i on macOS without an argument and getting sed: 1: "file.txt": extra characters at the end of s command — BSD sed needs sed -i '' '...' or sed -i.bak '...'.
  • Not escaping / inside a pattern or replacement, e.g. matching a path — switch the delimiter instead: sed 's#/usr/local#/opt#'.
  • Assuming sed edits the file directly by default; without -i it 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 -n with p to use sed as a precise line-range printer instead of head -n X | tail -n Y.

Best practices

  • Always test a sed substitution without -i first (or use -i.bak) so you can review the diff before overwriting a file you can't easily recover.
  • Prefer -E/-r for anything beyond a trivial substitution — basic regex escaping (\(, \|, \+) gets unreadable fast.
  • In portable scripts targeting both GNU and BSD sed, avoid -i entirely where possible; write to a temp file and mv it 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/' and sed 's/a/b/g'? Without g, only the first match per line is replaced; g replaces every match on the line.
  • How do you use sed to print a range of lines from a file? sed -n '10,20p' file-n suppresses default printing, and 10,20p prints only lines 10 through 20.
  • Why does sed -i behave differently on macOS than on Linux? macOS ships BSD sed, which requires an explicit (possibly empty) backup-suffix argument after -i, while GNU sed on 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.