Imagine needing to change a specific configuration setting across dozens of files, or update a repeated piece of text throughout a large log file. Manually editing each instance would take forever. This is precisely where the powerful Linux sed command (Stream EDitor) excels. More than just a simple find-and-replace tool, sed is a versatile utility designed to automate text transformations on the fly, allowing you to perform complex edits with concise instructions and saving countless hours.
For example, a single sed command can update IP addresses across dozens of configuration files after a network migration, standardize date formats in thousands of log entries, or sanitize sensitive data before sharing files—tasks that would take hours manually but complete in seconds with the right command.
This guide covers everything from basic find-and-replace operations to advanced regex patterns and multi-file editing. By the end, you’ll know how to use sed effectively and avoid the common pitfalls that trip up both newcomers and experienced users.
What You’ll Learn
In this guide, you’ll learn how to:
- Perform basic and global text replacements with precision
- Use regular expressions for advanced pattern matching
- Handle special characters and choose the right delimiters
- Apply line-specific transformations and targeted edits
- Combine sedwith other commands for complex workflows
- Troubleshoot common issues and cross-platform differences
Understanding the sed Command
Before jumping into examples, it helps to understand the basics. On most Linux distributions, GNU sed comes pre-installed, so you’re ready to go. For the most comprehensive details, you can always refer to the official GNU sed manual. At its core, sed is about making text manipulation simple and efficient.
Here’s the general syntax for finding and replacing text:
sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILELet’s break it down step by step:
- -i: This tells- sedto edit the file in place. If you want to keep a backup of the original file, you can add an extension like- .bak(e.g.,- -i.bak). On macOS (BSD sed), if you don’t want a backup, you must provide an empty string as an argument to- -i, for example,- -i ''. GNU sed allows- -iwithout an extension if no backup is desired. Note: GNU sed creates the backup file specified with- -i.SUFFIXeven if no actual changes are made to the file content.
- s: The substitute command, used for search-and-replace operations.
- Delimiters (/): While/is the default delimiter, you can use others like|or:if it makes your command easier to read.
- SEARCH_REGEX: The string or regular expression pattern you’re looking for.
- REPLACEMENT: The text you want to replace it with.
- g: The global flag. Without it, only the first match on each line is replaced. Add this to replace all matches.
With this foundation, you’re ready to start using sed to tackle text editing tasks of all sizes.
Quick Reference: Common sed Flags
Before diving into examples, here’s a quick reference table of the most frequently used sed flags:
| Flag | Purpose | Example | 
|---|---|---|
| -i | Edit file in-place (use -i.bakfor backup) | sed -i 's/old/new/g' file.txt | 
| -n | Suppress automatic output (use with pcommand) | sed -n '/pattern/p' file.txt | 
| -e | Execute multiple commands | sed -e 's/a/b/' -e 's/c/d/' file.txt | 
| -E | Enable extended regular expressions | sed -E 's/(a|b)/c/' file.txt | 
| -u | Unbuffered output (GNU sed only; low-latency streaming) | sed -u 's/foo/bar/g' logfile.txt | 
| g | Global replacement (all matches per line) | sed 's/old/new/g' file.txt | 
| I | Case-insensitive matching (GNU sed only) | sed 's/text/replacement/gI' file.txt | 
Basic sed Command Usage for String Replacement
Let’s start with the basics by looking at how to find and replace text in a file. Here’s an example using a file called file.txt with the following content:
123 Foo foo foo
foo /bin/bash Ubuntu foobar 456Replace the First Instance of a String
To replace only the first occurrence of a string on each line, you can use the following command:
sed -i 's/foo/linux/' file.txtOutput:
123 Foo linux foo
linux /bin/bash Ubuntu foobar 456Notice that only the first foo on each line was replaced, while other instances remain unchanged.
Replace All Occurrences of a String
To replace every occurrence of a string on each line, add the g flag for “global”:
sed -i 's/foo/linux/g' file.txtOutput:
123 Foo linux linux
linux /bin/bash Ubuntu linuxbar 456This replaces every instance of foo, including when it appears as part of another word, such as foobar.
Avoid Matching Substrings
If you don’t want sed to replace partial matches (like foo inside foobar), you can use word boundaries. In GNU sed, you can use \b as follows:
sed -i 's/\bfoo\b/linux/g' file.txtNote: The \b word boundary is supported in GNU sed. On macOS (BSD sed), use [[:<:]]foo[[:>:]] instead:
sed -E 's/[[:<:]]foo[[:>:]]/linux/g' file.txtOutput:
123 Foo linux linux
linux /bin/bash Ubuntu foobar 456Case-Insensitive Replacement
To make the replacement case-insensitive, include the I flag (GNU sed only):
sed -i 's/foo/linux/gI' file.txtNote: The I flag is available in GNU sed. On macOS (BSD sed), use a character class for case-insensitivity, e.g., [Ff]oo. Remember to use -i '' with BSD sed if you are editing in-place without a backup, as shown below:
sed -i '' 's/[Ff]oo/linux/g' file.txtOutput:
123 linux linux linux
linux /bin/bash Ubuntu linuxbar 456Replace Strings Containing Special Characters
If the string you’re replacing includes special characters like /, you’ll need to escape them with a backslash (\). For example, to replace /bin/bash with /usr/bin/zsh:
sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txtOr, use a different delimiter (like |) to make the command more readable. In fact, you can use almost any character as a delimiter, such as #, :, or _, as long as it does not appear in your search pattern or replacement string:
sed -i 's|/bin/bash|/usr/bin/zsh|g' file.txtOutput:
123 Foo foo foo
foo /usr/bin/zsh Ubuntu foobar 456Quick Tip:
- Test Before Committing Changes: Run your sedcommands without the-ioption to preview the changes before modifying the file.
- Always Create Backups: Use -i.bakto save a backup of the original file, just in case. For example:
sed -i.bak 's/foo/linux/g' file.txtWhat’s Next?
Ready for more advanced techniques? The next section covers regular expressions, line-specific replacements, and working with multiple files.
Advanced sed Operations
Once you’ve mastered the basics, you can move on to sed‘s more advanced capabilities. With support for regular expressions, line-specific operations, and complex text transformations, sed becomes an even more powerful tool for handling intricate text manipulation tasks.
Using Regular Expressions with sed for Advanced Matching
Regular expressions allow you to match patterns, not just literal strings. For instance, to replace all 3-digit numbers with the word number:
sed -i 's/\b[0-9]\{3\}\b/number/g' file.txtOutput:
number Foo foo foo
foo /bin/bash Ubuntu foobar numberThis matches only 3-digit numbers (e.g., 123 or 456) and replaces them, leaving other numbers unaffected.
Reusing the Matched Pattern with &
The & character corresponds to the matched pattern and can be used in the replacement string. For example, if you want to surround every 3-digit number with curly braces:
sed -i 's/\b[0-9]\{3\}\b/{&}/g' file.txtOutput:
{123} Foo foo foo
foo /bin/bash Ubuntu foobar {456}Here, {&} inserts the matched number between the curly braces.
Line-Specific String Replacements using sed
You can target specific lines or ranges of lines for replacement:
- Replace text on a specific line (e.g., line 2):
sed '2s/foo/linux/' file.txt- Replace text in a range of lines (e.g., lines 2 to 4):
sed '2,4s/foo/linux/' file.txtThe sed command gives you fine-grained control over where replacements occur, avoiding unintended changes.
Deleting Lines Matching a Pattern
You can delete all lines that contain a specific string. For example, to remove any line with the word Ubuntu:
sed '/Ubuntu/d' file.txtOutput:
123 Foo foo fooInserting or Appending Lines
To add a line before or after a specific pattern, use the i (insert) or a (append) commands. For example:
                
- Insert a line before every line containing foo:
Note: On macOS (BSD sed), the syntax for inserting/appending lines requires a backslash before the newline, and the text to be inserted/appended must appear on the immediately following line. For example, to insert:
sed '/foo/i\
This is a new line' file.txtAnd to append:
sed '/foo/a\
This is a new line' file.txtEnsure there are no trailing spaces after the backslash.
Changing Entire Lines
To replace entire lines that match a pattern, use the c (change) command. For example, to replace all lines containing foo with This is a new line:
sed '/foo/c\
This is a new line' file.txtNote: On macOS (BSD sed), the syntax for changing lines is similar to inserting/appending and requires a backslash before the newline, with the replacement text on the next line. For example:
sed '/foo/c\
This is a new line' file.txtOutput (assuming both original lines contained ‘foo’):
This is a new line
This is a new lineCombining Multiple sed Instructions
You can chain multiple instructions by separating them with semicolons. For instance, to replace foo with linux, delete lines containing Ubuntu, and append a line after bar:
sed -i 's/foo/linux/g;/Ubuntu/d;/bar/a\
This line was added' file.txtThis approach lets you perform complex transformations in a single command.
Using sed with Large Files or Multiple Directories
When working with large files or directories, combining sed with other tools like the find command or the grep command becomes incredibly useful:
- Recursive Search and Replace: Replace all occurrences of foowithbarin the current directory and its subdirectories:
find . -type f -exec sed -i 's/foo/bar/g' {} +Warning: This command, when combined with find -exec, will edit all files, including potentially binaries, in the directory tree. To avoid unintended changes, it is highly recommended to perform a dry run first. You can do this by replacing -exec sed -i 's/foo/bar/g' {} + with -print to list files that would be affected, or by running the sed command without -i and redirecting output to inspect. Always restrict to specific text file types if possible (see next example) or use the grep command to filter files first.
- Target Specific File Types: Replace foowithbaronly in.txtfiles:
find . -type f -name "*.txt" -exec sed -i 's/foo/bar/g' {} +Using grep for Matching Files: Search for files containing foo and replace it with bar, while creating backups:
grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g'These techniques allow you to handle large-scale text manipulations with precision. For more details on the grep command and its advanced search capabilities, check out our comprehensive grep command guide.
Tip: Use sed -u for Low-Latency Output
When you need sed to flush its output promptly—such as in streaming pipelines or when feeding logs into another process—enable unbuffered mode with the -u option:
sed -u 's/foo/bar/g' logfile.txtNote: Unbuffered mode prevents output from being held in sed’s buffers, which reduces latency but can slightly slow down throughput on very large files. GNU sed supports -u. BSD sed (macOS) lacks this flag and returns an illegal option error, so install GNU sed (e.g., brew install gnu-sed and run gsed -u ...) or pair sed with a line-buffering tool such as stdbuf -o0 from coreutils (installable via brew install coreutils) to approximate the same behavior. This trade-off makes -u ideal for real-time log monitoring or interactive pipelines where immediate output matters more than raw processing speed.
Troubleshooting Common sed Issues
While sed is powerful, you might encounter a few common issues. Here’s how to troubleshoot them:
1. Changes Not Happening or Incorrect Replacements
- Forgetting Global Replacement (g): If only the first match on each line is replaced, ensure you’ve added thegflag to your substitute command (e.g.,s/old/new/g) to replace all occurrences.
- Regex Errors: Special characters in your search pattern (like .,*,[,\) need to be escaped with a backslash (\). For example, to match a literal dot, use\.. Alternatively, for paths with slashes, use a different delimiter:sed 's|/path/to/old|/path/to/new|g'.
- Word Boundaries: If sedreplaces parts of words you didn’t intend (e.g., “man” in “manual”), use word boundaries. For GNU sed, use\b(e.g.,s/\bman\b/person/g). For BSD sed (macOS), use[[:<:]]and[[:>:]](e.g.,s/[[:<:]]man[[:>:]]/person/g).
- Case Sensitivity: By default, sedis case-sensitive. For case-insensitive search in GNU sed, use theIflag (e.g.,s/text/replacement/gI). For BSD sed, you might need to use character classes like[Tt][Ee][Xx][Tt].
2. Differences Between GNU sed (Linux) and BSD sed (macOS)
Syntax and feature differences between GNU sed (common on Linux) and BSD sed (used on macOS) are a frequent source of confusion:
- In-place Editing (-i):- GNU sed: -iedits in place without a backup.-i.bakcreates a backup. Note: GNUsedcreates the backup file specified with-i.SUFFIXeven if no actual changes are made to the file content.
- BSD sed: -irequires an extension for backup (e.g.,-i '.bak'). For no backup, provide an empty string:-i ''.
 
- GNU sed: 
- Extended Regular Expressions:
- GNU sed: Supports both -rand-E. The POSIX standard is-E, which is recommended for better portability.
- BSD sed: Uses -E.
 
- GNU sed: Supports both 
- Insert (i), Append (a), Change (c) Commands:- BSD sed: These commands strictly require the text to be on a new line, preceded by a backslash. Example: sed '/pattern/a\ Appended text' file.txt.
- GNU sed: More flexible, but following the BSD syntax is generally safer for portability.
 
- BSD sed: These commands strictly require the text to be on a new line, preceded by a backslash. Example: 
Tip: Always check your system’s man sed page for specifics.
3. “sed: -i may not be used with stdin” Error
The -i option (for in-place editing) modifies files directly and cannot be used when sed receives input from a pipe (stdin). If you’re piping output from another command to sed and want to save the changes, redirect the output to a new file:
some_command | sed 's/old/new/g' > output_file.txtIf you need to modify the original file in such a scenario, use a temporary file or more advanced shell constructs.
4. Avoiding Accidental File Modification
Before using -i to modify a file directly, it’s crucial to:
- Test without -i: Run yoursedcommand without-ifirst. This prints the modified output to the terminal, allowing you to verify the changes are correct before applying them to the file.
- Create Backups: Use -i.bak(GNU sed) or-i '.bak'(BSD sed) to create a backup of the original file. If something goes wrong, you can easily restore it.
5. Using sed on Binary Files
sed is designed for text files. Using it on binary files (like images or executables) can corrupt them. For binary file manipulation, tools like xxd or hexedit are more appropriate.
Related Linux Commands for Text Processing
While sed is powerful for stream editing and text transformations, combining it with other Linux text-processing commands becomes even more useful. Here are complementary tools with practical examples:
- grep – Search for patterns in files and filter text before or after sedprocessing. Example:grep -l "error" *.log | xargs sed -i 's/ERROR/WARN/g'finds all files containing “error” and replaces ERROR with WARN.
- awk – Extract and manipulate columnar data alongside pattern-based transformations. Example: awk '{print $3}' access.log | sed 's|/old/path|/new/path|g'extracts the third field then transforms paths.
- tr – Translate or delete characters for simple character-level transformations. Example: echo "Hello" | tr '[:lower:]' '[:upper:]' | sed 's/HELLO/GREETING/g'converts case then replaces words.
- cut – Extract sections from lines of text based on delimiters or character positions. Example: cut -d':' -f1 /etc/passwd | sed 's/root/admin/g'extracts usernames then modifies them.
- sort – Sort lines of text before processing with sed. Example:sort file.txt | sed 's/foo/bar/g'ensures consistent ordering during replacement.
- uniq – Remove or identify duplicate lines in processed output. Example: sed -E 's/[[:space:]]+/\n/g' file.txt | sort | uniqsplits words, sorts, and removes duplicates.
- tail – Monitor and process the end of files in real-time. Example: tail -f /var/log/syslog | sed -u 's/ERROR/[ERROR]/g'highlights errors in live logs.
Mastering these commands together creates a powerful text-processing toolkit for any Linux administrator or developer.
Conclusion
The sed command is one of those Linux utilities that pays off the time you invest in learning it. Whether you’re cleaning up config files, processing logs, or automating repetitive edits across dozens of files, sed turns hours of manual work into a single command.
Start with the basics—simple substitutions and global replacements—then gradually work your way into regular expressions and line-specific operations as you encounter real-world scenarios that need them. The key is to test your commands without -i first, create backups when editing in place, and remember that GNU sed (Linux) and BSD sed (macOS) have just enough differences to trip you up if you’re switching between systems.
The real power of sed shows up when you start combining it with other tools like grep, find, and awk. That’s when you go from “editing files” to “building text-processing pipelines” that handle thousands of files at once.
Your Turn
What’s the most useful sed one-liner you’ve discovered? Whether it’s a clever regex pattern, a specific use case, or a gotcha that cost you an hour of debugging, drop it in the comments. Other Linux users will appreciate it—and you might learn a new trick or two from their experiences.
 
					