# sed — Stream Editor for Text Transformation

> Filter and transform text with sed — substitution, in-place editing, line addressing, deletion and back-references for scripts and pipelines.

Source: https://www.jpkc.com/db/en/cheatsheets/files-text/sed/

<!-- PROSE:intro -->
sed (stream editor) reads text line by line and applies editing commands as the data flows through – no interactive editor, no temp files. Its bread and butter is search-and-replace with `s/pattern/replacement/`, but it also deletes, inserts, prints and reorders lines, addressed by number or by regex. You will reach for it whenever you need to patch config files, rewrite URLs, strip whitespace or massage command output in a pipeline. This guide walks from basic substitution through in-place editing, line addressing and back-references to the recipes you actually use.
<!-- PROSE:intro:end -->

## Basic Substitution

`sed 's/<pattern>/<replacement>/' <file>` — Replace the first occurrence of pattern on each line.

```bash
sed 's/foo/bar/' input.txt
```

`sed 's/<pattern>/<replacement>/g' <file>` — Replace all occurrences of pattern on each line (global).

```bash
sed 's/foo/bar/g' input.txt
```

`sed 's/<pattern>/<replacement>/gi' <file>` — Replace all occurrences, case-insensitive.

```bash
sed 's/error/warning/gi' log.txt
```

`sed 's/<pattern>/<replacement>/2' <file>` — Replace only the Nth occurrence of pattern on each line.

```bash
sed 's/the/THE/2' input.txt
```

`sed 's/<pattern>/<replacement>/gp' <file>` — Replace globally and print only the changed lines (use with -n).

```bash
sed -n 's/error/ERROR/gp' log.txt
```

## In-Place Editing

`sed -i 's/<pattern>/<replacement>/g' <file>` — Edit the file in-place (modifies the original file directly).

```bash
sed -i 's/localhost/production.example.com/g' config.yml
```

`sed -i.bak 's/<pattern>/<replacement>/g' <file>` — Edit in-place and create a backup with the given suffix.

```bash
sed -i.bak 's/debug=true/debug=false/g' config.ini
```

`sed -i '' 's/<pattern>/<replacement>/g' <file>` — Edit in-place without backup (macOS/BSD syntax, empty suffix required).

```bash
sed -i '' 's/old/new/g' config.yml
```

`sed -i 's/<pattern>/<replacement>/g' <file1> <file2>` — Edit multiple files in-place with the same substitution.

```bash
sed -i 's/v1.0/v2.0/g' README.md CHANGELOG.md
```

## Delimiters & Special Characters

`sed 's|<pattern>|<replacement>|g' <file>` — Use | as delimiter instead of /. Useful when patterns contain slashes.

```bash
sed 's|/usr/local|/opt|g' paths.conf
```

`sed 's#<pattern>#<replacement>#g' <file>` — Use # as delimiter. Any character can serve as delimiter.

```bash
sed 's#http://#https://#g' urls.txt
```

`sed 's/[[:space:]]*$//' <file>` — Remove trailing whitespace from each line.

```bash
sed 's/[[:space:]]*$//' source.py
```

`sed 's/^[[:space:]]*//' <file>` — Remove leading whitespace from each line.

```bash
sed 's/^[[:space:]]*//' messy.txt
```

`sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g' <file>` — Escape HTML special characters.

```bash
sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g' input.html
```

## Address Selection (Line Targeting)

`sed '<n>s/<pattern>/<replacement>/' <file>` — Substitute only on a specific line number.

```bash
sed '3s/old/new/' config.txt
```

`sed '<n>,<m>s/<pattern>/<replacement>/g' <file>` — Substitute on a range of lines (from line n to line m).

```bash
sed '10,20s/foo/bar/g' data.txt
```

`sed '$s/<pattern>/<replacement>/' <file>` — Substitute only on the last line. $ addresses the last line.

```bash
sed '$s/$/;/' data.csv
```

`sed '/<regex>/s/<pattern>/<replacement>/g' <file>` — Substitute only on lines matching a regex pattern.

```bash
sed '/^#/s/TODO/DONE/g' script.sh
```

`sed '/<start>/,/<end>/s/<pattern>/<replacement>/g' <file>` — Substitute within a range defined by two regex patterns.

```bash
sed '/<body>/,/<\/body>/s/class="old"/class="new"/g' page.html
```

`sed '1,/<pattern>/s/<old>/<new>/g' <file>` — Substitute from the first line until a pattern is matched.

```bash
sed '1,/---/s/draft/published/g' post.md
```

`sed '0~2s/<pattern>/<replacement>/g' <file>` — Substitute on every 2nd line (GNU sed step address: start~step).

```bash
sed '0~2s/^/>> /' data.txt
```

## Deleting Lines

`sed '<n>d' <file>` — Delete a specific line by number.

```bash
sed '5d' data.txt
```

`sed '<n>,<m>d' <file>` — Delete a range of lines.

```bash
sed '3,7d' data.txt
```

`sed '$d' <file>` — Delete the last line of the file.

```bash
sed '$d' data.txt
```

`sed '/<pattern>/d' <file>` — Delete all lines matching a pattern.

```bash
sed '/^#/d' config.ini
```

`sed '/^$/d' <file>` — Delete all empty lines.

```bash
sed '/^$/d' messy.txt
```

`sed '/^[[:space:]]*$/d' <file>` — Delete all blank lines (empty or whitespace-only).

```bash
sed '/^[[:space:]]*$/d' messy.txt
```

`sed '/<start>/,/<end>/d' <file>` — Delete all lines between two patterns (inclusive).

```bash
sed '/BEGIN_GENERATED/,/END_GENERATED/d' output.txt
```

`sed '/<pattern>/!d' <file>` — Delete all lines NOT matching a pattern (inverse, like grep).

```bash
sed '/ERROR/!d' log.txt
```

## Inserting & Appending

`sed '<n>i\<text>' <file>` — Insert text before a specific line.

```bash
sed '1i\# Configuration File' config.ini
```

`sed '<n>a\<text>' <file>` — Append text after a specific line.

```bash
sed '5a\# New section starts here' config.ini
```

`sed '/<pattern>/i\<text>' <file>` — Insert text before lines matching a pattern.

```bash
sed '/\[database\]/i\# Database settings' config.ini
```

`sed '/<pattern>/a\<text>' <file>` — Append text after lines matching a pattern.

```bash
sed '/^server {/a\    listen 443 ssl;' nginx.conf
```

`sed '<n>c\<text>' <file>` — Replace (change) an entire line with new text.

```bash
sed '3c\new_value = true' config.ini
```

`sed '/<pattern>/c\<text>' <file>` — Replace entire lines matching a pattern with new text.

```bash
sed '/^debug=/c\debug=false' config.ini
```

## Back-References & Groups

`sed 's/\(<pattern>\)/\1<suffix>/g' <file>` — Capture a group with \( \) and reference it with \1 in the replacement.

```bash
sed 's/\(version\)=.*/\1=2.0/' config.ini
```

`sed -E 's/(<pattern>)/\1<suffix>/g' <file>` — Extended regex mode. Use ( ) for groups instead of \( \).

```bash
sed -E 's/(version)=.*/\1=2.0/' config.ini
```

`sed -E 's/(<p1>)(<p2>)/\2\1/g' <file>` — Swap two captured groups using back-references.

```bash
sed -E 's/([a-z]+), ([a-z]+)/\2 \1/g' names.txt
```

`sed 's/.*/(&)/' <file>` — The & in replacement refers to the entire matched text.

```bash
sed 's/.*/(&)/' list.txt
```

`sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3.\2.\1/g' <file>` — Reformat dates from YYYY-MM-DD to DD.MM.YYYY using three groups.

```bash
sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3.\2.\1/g' dates.txt
```

## Printing & Output Control

`sed -n '<n>p' <file>` — Print only a specific line. -n suppresses default output.

```bash
sed -n '10p' data.txt
```

`sed -n '<n>,<m>p' <file>` — Print a range of lines.

```bash
sed -n '5,15p' data.txt
```

`sed -n '/<pattern>/p' <file>` — Print only lines matching a pattern (like grep).

```bash
sed -n '/ERROR/p' log.txt
```

`sed -n '/<start>/,/<end>/p' <file>` — Print lines between two patterns (inclusive).

```bash
sed -n '/BEGIN/,/END/p' config.txt
```

`sed -n '$=' <file>` — Print the total number of lines in the file (like wc -l).

```bash
sed -n '$=' data.txt
```

`sed '/<pattern>/q' <file>` — Quit after printing the first line matching a pattern.

```bash
sed '/^END$/q' stream.txt
```

## Multiple Commands

`sed -e 's/<p1>/<r1>/g' -e 's/<p2>/<r2>/g' <file>` — Apply multiple substitution commands with -e flags.

```bash
sed -e 's/foo/bar/g' -e 's/baz/qux/g' input.txt
```

`sed 's/<p1>/<r1>/g; s/<p2>/<r2>/g' <file>` — Chain multiple commands with semicolons.

```bash
sed 's/http/https/g; s/www\.//g' urls.txt
```

`sed -f <script_file> <file>` — Read sed commands from a script file (one command per line).

```bash
sed -f transforms.sed input.txt
```

`sed '{ s/<p1>/<r1>/g; s/<p2>/<r2>/g; }' <file>` — Group multiple commands with curly braces.

```bash
sed '/^title/{ s/old/new/g; s/draft/final/g; }' document.md
```

## Transliteration

`sed 'y/<source_chars>/<dest_chars>/' <file>` — Transliterate characters (like tr). Maps each character one-to-one.

```bash
sed 'y/abc/ABC/' input.txt
```

`sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' <file>` — Convert all uppercase letters to lowercase.

```bash
sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' input.txt
```

## Common Recipes

`sed -E 's/^[[:space:]]+|[[:space:]]+$//g' <file>` — Trim leading and trailing whitespace from each line.

```bash
sed -E 's/^[[:space:]]+|[[:space:]]+$//g' messy.txt
```

`sed '/^$/N;/^\n$/d' <file>` — Squeeze multiple consecutive blank lines into one.

```bash
sed '/^$/N;/^\n$/d' messy.txt
```

`sed 's/^/    /' <file>` — Indent every line by 4 spaces.

```bash
sed 's/^/    /' code.py
```

`sed '=' <file> | sed 'N;s/\n/\t/'` — Add line numbers followed by a tab to each line.

```bash
sed '=' script.sh | sed 'N;s/\n/\t/'
```

`sed -E 's/([^ ]+)/"\1"/g' <file>` — Wrap each word in double quotes.

```bash
sed -E 's/([^ ]+)/"\1"/g' words.txt
```

`sed -E 's/,.*//' <file>` — Extract the first field from a CSV (everything before the first comma).

```bash
sed -E 's/,.*//' data.csv
```

`sed -e :a -e '/\\$/N; s/\\\n//; ta' <file>` — Join lines ending with a backslash (line continuation).

```bash
sed -e :a -e '/\\$/N; s/\\\n//; ta' Makefile
```

## Pipelines

`<command> | sed 's/<pattern>/<replacement>/g'` — Use sed as a filter in a pipeline to transform output.

```bash
cat /etc/passwd | sed 's/:.*//'
```

`<command> | sed -n '/<pattern>/p'` — Filter output to show only matching lines.

```bash
env | sed -n '/^PATH/p'
```

`<command> | sed '1d'` — Remove the first line (header) from command output.

```bash
docker ps | sed '1d'
```

`<command> | sed 's/\x1b\[[0-9;]*m//g'` — Strip ANSI color codes from command output.

```bash
ls --color=always | sed 's/\x1b\[[0-9;]*m//g'
```

<!-- PROSE:outro -->
## Conclusion

sed turns repetitive text edits into one-liners you can drop into scripts and pipelines. For everyday work, `s///g`, line deletion with `d` and selective printing with `-n …p` cover most cases. The one flag to treat with respect is `-i`: it overwrites the original file with no undo, so get into the habit of writing `-i.bak` to keep a backup – or run the command without `-i` first and eyeball the output. Be aware of GNU/BSD differences: GNU sed takes `-i` with no argument, whereas BSD/macOS sed requires `sed -i ''`; step addresses like `0~2` and `\x1b` escapes are GNU extensions too.

## Further Reading

- [GNU sed manual](https://www.gnu.org/software/sed/manual/sed.html) – complete reference with all commands and addressing modes
- [grymoire sed tutorial](https://www.grymoire.com/Unix/Sed.html) – classic, example-driven introduction to sed
<!-- PROSE:outro:end -->

## Related Commands

- [awk](https://www.jpkc.com/db/en/cheatsheets/files-text/awk/) – field-aware text processing for column data and reports
- [grep](https://www.jpkc.com/db/en/cheatsheets/files-text/grep/) – find the lines first, then transform them with sed
- [tr](https://www.jpkc.com/db/en/cheatsheets/files-text/tr/) – fast character-level translation and deletion

