Chapter 21: Bash Stream Editor (sed)
What is sed? (super simple first)
sed = stream editor It’s a tool that reads text line-by-line (from a file or from pipe), makes changes automatically, and prints the result (usually to screen or new file).
Think of it as:
- Find-and-replace on steroids for the whole file/stream
- A non-interactive editor (no opening vim/nano – it works in scripts & pipelines)
- Perfect for: cleaning logs, updating configs, renaming variables in code, removing lines, adding headers/footers, etc.
Most people use sed for substitution (replace text), but it can also delete, insert, print selectively, and more.
Basic syntax (memorize this pattern)
|
0 1 2 3 4 5 6 7 8 |
sed 'command' file.txt # show changed version on screen sed 'command' < file.txt > new.txt # save to new file sed -i 'command' file.txt # edit file IN PLACE (dangerous but useful!) |
The most common command is substitution:
|
0 1 2 3 4 5 6 7 |
sed 's/old/new/' file.txt # replace first "old" with "new" per line sed 's/old/new/g' file.txt # g = global → replace ALL occurrences per line |
1. Create a test file right now (copy-paste this)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
cat > story.txt << 'EOF' Hello Arman from Hyderabad! Hyderabad is awesome city in Telangana. I love Hyderabad food like biryani. Hyderabad weather is hot in 2026. Hyderabad Hyderabad Hyderabad – too many times! Error: something went wrong in Hyderabad. EOF |
2. Super basic examples (try these now!)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# Replace first "Hyderabad" with "Secunderabad" in each line sed 's/Hyderabad/Secunderabad/' story.txt # Replace ALL "Hyderabad" (global flag g) sed 's/Hyderabad/Secunderabad/g' story.txt # Case insensitive replace (i flag – GNU sed) sed 's/hyderabad/Secunderabad/gi' story.txt # Change only first occurrence in whole file (no g, but only first line usually) sed 's/Hyderabad/Secunderabad/' story.txt # Replace nth occurrence per line (e.g. 2nd) sed 's/Hyderabad/Secunderabad/2' story.txt # → changes only the second "Hyderabad" in lines that have multiple |
3. Very common options (you’ll use these daily)
| Option | What it does | Example command | Why useful? |
|---|---|---|---|
| -i | Edit file in place (overwrite original) | sed -i ‘s/old/new/g’ config.txt | Update files directly |
| -i.bak | Edit in place + make backup | sed -i.bak ‘s/old/new/g’ file.txt | Safe – keeps original as .bak |
| -e | Multiple commands | sed -e ‘s/a/b/’ -e ‘s/x/y/’ file.txt | Chain changes |
| -r or -E | Use extended regex (modern) | sed -E 's/(old |
bad)/good/g' file.txt |
| -n | Suppress auto-print (use with p) | sed -n ‘/pattern/p’ file.txt | Like grep |
| -f | Read commands from script file | sed -f changes.sed file.txt | Complex scripts |
4. Delete lines (very powerful)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# Delete lines containing "Error" sed '/Error/d' story.txt # Delete empty lines sed '/^$/d' file.txt # Delete lines starting with # sed '/^#/d' config.conf # Delete from line 3 to 5 sed '3,5d' file.txt # Keep only lines with "Hyderabad" sed -n '/Hyderabad/p' story.txt # -n + p = print only matching (like grep) |
5. Insert / Append lines
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# Insert line BEFORE line 2 sed '2iNew line inserted before line 2' story.txt # Append AFTER line 3 sed '3aNew line after line 3' story.txt # Add at beginning of file sed '1iHeader: My Report 2026' file.txt # Add at end sed '$aFooter: End of file' file.txt |
6. Change delimiter (when pattern has / )
|
0 1 2 3 4 5 6 7 8 9 10 11 |
# Normal fails because / in path sed 's//usr/local//opt/local/g' config.txt # wrong! # Use different delimiter (common: # @ % ) sed 's#/usr/local#/opt/local#g' config.txt sed 's|/usr/local|/opt/local|g' config.txt |
7. Capture groups & backreferences (advanced but useful)
|
0 1 2 3 4 5 6 7 8 9 10 11 |
# Swap first and last name (assume "First Last") sed -E 's/([A-Za-z]+) ([A-Za-z]+)/\2, \1/' names.txt # John Doe → Doe, John # Add quotes around emails sed -E 's/([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/"\1"/g' contacts.txt |
8. Real-world examples you will use daily
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# Update version in all config files sed -i 's/version: 1.2.3/version: 1.3.0/g' *.yaml # Comment out debug lines sed -i 's/^debug:/#debug:/' app.conf # Remove ANSI color codes from logs sed -r 's/\x1B\[[0-9;]*[mK]//g' colored.log > clean.log # Change localhost to domain in dev → prod sed -i 's/localhost/myapp.com/g' *.js *.html # Number lines (add line number) sed = story.txt | sed 'N;s/\n/\t/' # Replace tabs with 4 spaces sed 's/\t/ /g' file.txt # Multiple replacements in one go sed -e 's/old/new/g' -e 's/bad/good/g' -e '/Error/d' log.txt |
9. Quick cheat-sheet table
| Goal | Command example |
|---|---|
| Replace first match per line | sed ‘s/old/new/’ file |
| Replace all matches | sed ‘s/old/new/g’ file |
| Case insensitive | sed ‘s/old/new/gi’ file |
| In-place edit + backup | sed -i.bak ‘s/old/new/g’ file |
| Delete matching lines | sed ‘/pattern/d’ file |
| Print only matching lines | sed -n ‘/pattern/p’ file |
| Insert before line N | sed ‘NiNew text’ file |
| Append after line N | sed ‘NaNew text’ file |
| Use different delimiter | `sed ‘s |
| Swap words with capture | sed -E ‘s/(\w+) (\w+)/\2 \1/’ file |
10. Pro tips from daily use
- Always test without -i first → see output on screen
- Use -i.bak until you’re 100% sure
- Quote commands ‘…’ to protect from shell
- For very complex → put in file: sed -f myscript.sed file
- sed + pipes = power: cat log | grep error | sed ‘s/time=[0-9]*//’
Now open terminal and try these 3:
|
0 1 2 3 4 5 6 7 8 |
sed 's/Hyderabad/Secunderabad/g' story.txt sed -n '/biryani/p' story.txt sed '/Hyderabad/ s/food/hyderabadi food/' story.txt # replace only in matching lines |
Tell me what you see! Or ask:
- “How to replace only between quotes?”
- “How to number only error lines in log?”
- “Best sed for cleaning CSV files?”
We’ll build exact commands together! 😄
