I still remember the first time sed saved my bacon. It was 2 AM, I was three cups of coffee deep, and I’d just deployed a configuration change that broke API endpoints across 47 microservices. The change? One wrong URL in a config file that got templated everywhere. Rolling back would’ve taken hours. Instead, I wrote a one-line sed command that fixed every instance in under 30 seconds.
That night, I became a sed believer.
sed (stream editor) is a non-interactive text editor that processes files line-by-line, making it perfect for quick edits, bulk changes, and automation scripts. Unlike opening files in vim or nano, sed can transform thousands of files in seconds without human interaction. It’s the difference between spending your afternoon clicking through files and writing one command that does it all.
What is sed and Why You Actually Need It
sed is a stream-oriented text processor that reads input line by line, applies commands to each line, and outputs the results. Think of it as an assembly line for text – every line goes through, gets processed according to your instructions, and comes out the other side modified.
Here’s why sed matters in real-world system administration:

- Speed – Process gigabytes of log files without loading them into memory
- Automation – Perfect for shell scripts and CI/CD pipelines
- Universality – Available on every Unix-like system, from minimal Docker containers to ancient production servers
- Power – Complex text transformations in a single command
I’ve used sed to fix emergency production issues, process massive log files, sanitize data exports, and automate configuration updates. It’s one of those tools that you don’t appreciate until 2 AM when you need to change 10,000 lines of config and sed is the only thing standing between you and a very long night.
Basic sed Syntax: Understanding the Command Structure
The basic sed command follows this pattern:
sed [options] 'command' filenameOr using pipes:
command | sed 'command'The most important thing to understand is that sed doesn’t modify the original file by default. It reads the file, processes it, and prints the result to stdout. This is actually a feature – you can test your command before committing to changes.
Let’s break down a simple example:
sed 's/error/ERROR/' server.logThis reads server.log, replaces the first occurrence of “error” with “ERROR” on each line, and prints the result to your terminal. The original file remains untouched.
The Substitute Command: Your Most-Used Tool
The s command (substitute) is what you’ll use 80% of the time. The syntax is:
s/pattern/replacement/flagsCommon flags include:
g– Global replacement (all occurrences on each line, not just the first)i– Case-insensitive matchingp– Print lines where substitution occurred- A number (like
2) – Replace only the nth occurrence
Essential sed Examples You’ll Actually Use
Let me show you the sed commands I use weekly. These aren’t textbook examples – they’re the real-world operations that solve actual problems.
Replace All Occurrences in a File
sed 's/old_domain.com/new_domain.com/g' config.iniThis replaces every instance of the old domain with the new one. Without the g flag, it would only replace the first occurrence on each line – a mistake that’s bitten me more times than I’d like to admit.
Edit Files In-Place (The Dangerous One)
sed -i 's/DEBUG/INFO/g' application.confThe -i flag edits the file directly. This is powerful but risky. I always test without -i first, or use -i.bak to create a backup:
sed -i.bak 's/DEBUG/INFO/g' application.confThis creates application.conf.bak before making changes. Trust me, the one time you skip the backup is when you’ll need it.
sed -i without testing first. I once watched a junior admin accidentally replace every instance of “1” in a config file, turning “127.0.0.1” into “27.0.0.” and bringing down an entire service cluster. Test your pattern, verify the output, then commit.Delete Lines Matching a Pattern
sed '/^#/d' config.confThis deletes all lines starting with # (comments). The d command means “delete”, and the pattern uses regex where ^ means “start of line”.
I use this constantly when processing config files or cleaning up data exports. Want to remove blank lines? Use this:
sed '/^$/d' messy_file.txtPrint Only Specific Lines
sed -n '10,20p' large_file.logThis prints lines 10 through 20. The -n flag suppresses automatic printing (otherwise you’d see everything), and p prints the matching lines. It’s faster than opening a 10GB log file in less when you know exactly which lines you need.
Print every line matching a pattern:
sed -n '/ERROR/p' application.logThis works like grep, but sed gives you more flexibility for follow-up processing. Speaking of which, if you’re doing serious log analysis with journalctl, combining it with sed can be incredibly powerful.
Multiple Substitutions in One Command
sed -e 's/foo/bar/g' -e 's/old/new/g' file.txtOr use semicolons:
sed 's/foo/bar/g; s/old/new/g' file.txtI prefer the semicolon method for readability, but -e is clearer when commands get complex.
Real-World sed Use Cases from Production
Let me share some scenarios where sed has saved significant time and prevented late-night panic.
Fixing API Endpoints Across Multiple Files
Remember that 2 AM disaster I mentioned? Here’s the actual command I used:
find /var/www/configs -type f -name "*.yaml" -exec sed -i.bak 's|api.staging.example.com|api.production.example.com|g' {} \;This combines find with sed to recursively fix every YAML file. Notice I used | as the delimiter instead of / – when your pattern contains slashes (like URLs), changing delimiters prevents “leaning toothpick syndrome” where you’re escaping slashes everywhere.
Sanitizing Log Files for Sharing
sed -E 's/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/XXX.XXX.XXX.XXX/g' server.log > sanitized.logThis replaces all IP addresses with X’s before sharing logs with external support. The -E flag enables extended regex, making the pattern more readable.
Commenting Out Configuration Sections
sed '/^database_password/s/^/#/' app.confThis finds lines starting with “database_password” and adds a # at the beginning. The pattern /^database_password/ selects the line, and s/^/#/ adds the comment character.
Extracting Data Between Tags
sed -n '/<error>/,/<\/error>/p' log.xmlThis prints everything between <error> and </error> tags. The comma creates a range – it starts printing when it finds the first pattern and stops after the second.
sed vs awk: When to Use Which
People always ask: “Should I use sed or awk?” Here’s my rule of thumb after a decade of using both:
Use sed when:
- You’re doing simple find-and-replace operations
- You need to edit files in-place
- You’re working with entire lines as units
- The task is straightforward text transformation
Use awk when:
- You need to process column-based data
- You’re doing arithmetic or comparisons
- You need conditional logic (if-else statements)
- You’re generating formatted reports from data
The difference between sed, awk, and grep comes down to their design goals. sed is a stream editor for transforming text, awk is a data extraction and reporting tool, and grep is for pattern matching. They often work great together in pipelines.
In practice, I reach for sed when I can describe the task as “find X and replace with Y” or “delete lines matching Z”. If I start thinking about fields, columns, or calculations, that’s awk territory.
Common sed Mistakes and How to Avoid Them
I’ve made every sed mistake in the book. Here are the ones that’ll bite you if you’re not careful.
Forgetting the Global Flag
# Wrong - only replaces first occurrence per line
sed 's/error/ERROR/' log.txt
# Right - replaces all occurrences
sed 's/error/ERROR/g' log.txtThis one gets everyone eventually. You think your command worked, but half the instances are still unchanged because you forgot /g.
Using the Wrong Quotes
# Won't work - double quotes let shell expand variables
sed "s/old/new/g" file.txt
# Better - single quotes protect your pattern
sed 's/old/new/g' file.txtUse single quotes unless you specifically need shell variable expansion. Double quotes can cause unexpected behavior when your pattern contains special characters.
Not Escaping Special Characters
sed uses Basic Regular Expressions (BRE) by default, not Perl-style regex. This means:
.matches any character (use\.for a literal period)+is literal (use\+for “one or more”)?is literal (use\?for “zero or one”)
Or use -E for extended regex and avoid most escaping headaches.
Delimiter Confusion with Paths
# Hard to read - "leaning toothpick syndrome"
sed 's/\/var\/www\/old/\/var\/www\/new/g' config
# Much better - use a different delimiter
sed 's|/var/www/old|/var/www/new|g' configYou can use almost any character as a delimiter. I typically use | for paths, @ for email patterns, and # when working with file permissions.
Advanced sed Techniques Worth Learning
Once you’re comfortable with basic substitutions, these advanced patterns will expand what’s possible.
Using Capture Groups and Backreferences
sed 's/\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\)/\2\/\3\/\1/' dates.txtThis converts dates from 2025-09-15 to 09/15/2025 format. The \( \) creates capture groups, and \1, \2, \3 reference them. Yeah, the escaping is ugly in BRE – this is where sed -E helps.
Conditional Replacements
sed '/production/s/DEBUG/WARNING/' config.iniThis only performs the substitution on lines containing “production”. The pattern before the substitution acts as a filter.
Inserting Lines Before or After a Match
# Insert before
sed '/database_host/i\# Database configuration' config.txt
# Append after
sed '/database_host/a\database_port=5432' config.txtThe i command inserts text before the matched line, a appends after. This is incredibly useful when programmatically building config files.
Reading Commands from a File
For complex operations, put your sed commands in a file:
sed -f transform.sed input.txtYour transform.sed might contain:
s/foo/bar/g
/^#/d
s/DEBUG/INFO/giThis makes complex transformations maintainable and reusable. I keep a collection of sed scripts for common tasks like log sanitization before backup.
Combining sed with Other Commands
sed shines in pipelines. Here are some combinations I use regularly.
Processing Archives On-the-Fly
tar -xzOf backup.tar.gz config.ini | sed 's/old_value/new_value/g' > modified_config.iniThis extracts a file from a tar archive, processes it with sed, and saves the result – all without extracting the entire archive.
Filtering Process Lists
ps aux | sed -n '/httpd/p' | sed 's/ */ /g'First sed filters for httpd processes, second compresses multiple spaces to single spaces for cleaner output.
Quick Data Pipeline
cat access.log | sed -n '/404/p' | sed 's/^.*"GET \(.*\) HTTP.*$/\1/' | sort | uniq -c | sort -rnThis extracts all 404’d URLs from an access log, counts them, and sorts by frequency. It’s the kind of one-liner that impresses in incident post-mortems.
sed Performance and When to Use Alternatives
sed is fast, but it’s not always the right tool. Here’s what I’ve learned about performance.
For small to medium files (under 100MB), sed performance is excellent. For massive files or high-frequency processing, consider these factors:
- Memory usage – sed is a stream processor, so it handles huge files without loading them entirely into memory
- Regex complexity – Complex patterns slow things down. If you’re doing lots of backreferences, consider Perl or Python
- Multiple passes – Each sed invocation reads the file. Combine operations when possible
I’ve processed 50GB log files with sed without issues. The key is writing efficient patterns and avoiding unnecessary complexity.
When not to use sed:
- Binary files – use specialized tools
- Complex data transformations requiring state – use Python or Perl
- Column-heavy data processing – use awk
- When you need IDE features and debugging – use a proper scripting language
Learning sed: Resources and Next Steps
The best way to learn sed is to use it. Start with simple substitutions, gradually add complexity, and keep the GNU sed manual bookmarked.
I learned sed by:
- Solving small, real problems (“I need to change this config”)
- Reading other people’s sed scripts and understanding what they do
- Building a personal collection of useful patterns
- Teaching others (you don’t really understand something until you explain it)
The DigitalOcean sed guide is excellent for structured learning. For deeper understanding, the classic Grymoire sed tutorial covers the internals and advanced patterns.
Your sed Journey Starts Now
sed isn’t glamorous. Nobody puts “sed expert” on their resume or brags about it at meetups. But it’s one of those fundamental skills that separates administrators who fight their tools from those who make them work efficiently.
The next time you’re faced with editing 50 config files or processing a massive log, remember: there’s probably a sed one-liner that’ll do it in seconds. And once you’ve written that command and watched it execute flawlessly across thousands of lines, you’ll understand why this 40-year-old tool is still essential.
Start simple. Replace one thing in one file. Then try it on multiple files. Add a regex. Chain commands together. Before you know it, you’ll be the person others ask when they need text transformed quickly.
And maybe, just maybe, sed will save your bacon at 2 AM too.





