sed Command in Linux (Find and Replace Strings in Files)

Last updated Wednesday, February 11, 2026 12:35 pm Joshua James 14 min read

The Linux sed command (Stream EDitor) finds and replaces text in files directly from the terminal. Instead of opening each file in an editor, a single sed command can update configuration values, rewrite log entries, or sanitize data across entire directory trees.

This guide covers basic and global replacement, regular expressions for pattern matching, delimiter and special-character handling, line-specific and multi-file editing, cross-platform differences, and troubleshooting common issues.

Understand the sed Command

sed reads input line by line, applies the instructions you provide, and writes the result without launching a full-screen editor. GNU sed ships with almost every Linux distribution, and the official GNU sed manual covers additional edge cases beyond this guide.

In practice, a single command can update IP addresses across dozens of configuration files after a network migration, standardize date formats in thousands of log entries, or strip sensitive fields before sharing data. At its simplest, you replace one word with another and print the result without touching the original file:

sed 's/Linux/GNU\/Linux/' release-notes.txt

Adding -i turns that same command into an in-place edit. Test without -i first so you can confirm the output before writing to disk.

Here’s the general syntax for finding and replacing text:

sed [-i[SUFFIX]] 's/SEARCH_REGEX/REPLACEMENT/FLAGS' INPUTFILE

Let’s break it down step by step:

  • -i: This tells sed to 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 -i without an extension if no backup is desired.
  • 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:

TaskOptionsWhat They Do
Edit files in place safely-i, -i.bakApply changes directly to the file, optionally keeping a backup with a suffix such as .bak.
Preview matches before writing-n '/pattern/p'Suppress automatic printing so only lines matching the pattern are shown.
Run multiple edits at once-e 's/a/b/' -e 's/c/d/'Chain several substitutions in a single command.
Use extended regular expressions-EEnable features like grouping without extra escaping for parentheses and braces.
Stream output immediately-uTurn on unbuffered output to reduce latency in pipelines and log monitoring.
Replace every match on a lines/old/new/gAdd the global flag so every occurrence is replaced, not just the first match per line.
Match text without case sensitivitys/text/replacement/gIInclude the I flag so GNU sed treats uppercase and lowercase letters the same.

Verify sed Is Available

Most Linux installations include sed by default, but stripped-down containers and rescue images sometimes leave it out. Verify that it’s available before you start scripting:

command -v sed
/usr/bin/sed

Confirm the installed version with:

sed --version | head -1
sed (GNU sed) 4.9

If the command returns a path, you’re set. Otherwise install sed with your distribution’s package manager.

Ubuntu and Debian-Based Distributions

sudo apt update
sudo apt install sed

Fedora, RHEL, Rocky Linux, and AlmaLinux

sudo dnf install sed

Arch Linux and Manjaro

sudo pacman -S sed

openSUSE

sudo zypper install sed

Alpine Linux

sudo apk add sed

macOS (Homebrew)

brew install gnu-sed

Homebrew installs GNU sed as gsed so you can opt into GNU-only features like the I flag while keeping the system’s BSD sed untouched. For other platforms, building from source is rarely necessary unless you’re targeting a specific sed version.

Alpine Linux ships BusyBox sed by default, which lacks several GNU-specific features used in this guide (\b word boundaries, the I case-insensitive flag, and -u unbuffered mode). Running apk add sed replaces BusyBox sed with the full GNU version.

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 456

Example 1: Replace 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 's/foo/linux/' file.txt

Output:

123 Foo linux foo
linux /bin/bash Ubuntu foobar 456

Notice that only the first foo on each line was replaced, while other instances remain unchanged. This prints the modified text to your terminal; add -i (or -i.bak) when you’re ready to write the change back to disk.

Example 2: Replace All Occurrences of a String

To replace every occurrence of a string on each line, add the g flag for “global”:

sed 's/foo/linux/g' file.txt

Output:

123 Foo linux linux
linux /bin/bash Ubuntu linuxbar 456

This replaces every instance of foo, including when it appears as part of another word, such as foobar. The original file remains untouched until you repeat the command with -i.

Example 3: 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 's/\bfoo\b/linux/g' file.txt

The \b word boundary is supported in GNU sed. On macOS (BSD sed), use [[:<:]]foo[[:>:]] instead:

sed -E 's/[[:<:]]foo[[:>:]]/linux/g' file.txt

Output:

123 Foo linux linux
linux /bin/bash Ubuntu foobar 456

Notice that capital Foo remains unchanged because word boundaries are case-sensitive. The pattern \bfoo\b only matches lowercase “foo” as a complete word, leaving foobar (partial match) and Foo (different case) untouched.

Example 4: Perform Case-Insensitive Replacement

To make the replacement case-insensitive, include the I flag (GNU sed only):

sed 's/foo/linux/gI' file.txt

The I flag is available in GNU sed. On macOS (BSD sed), preview the change with a character class for case-insensitivity, such as [Ff]oo:

sed 's/[Ff]oo/linux/g' file.txt

If you do want to edit in place on macOS, provide an empty string to -i so BSD sed skips creating a backup file:

sed -i '' 's/[Ff]oo/linux/g' file.txt

Output:

123 linux linux linux
linux /bin/bash Ubuntu linuxbar 456

Example 5: Replace 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 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txt

Or, 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 's|/bin/bash|/usr/bin/zsh|g' file.txt

Output:

123 Foo foo foo
foo /usr/bin/zsh Ubuntu foobar 456

Example 6: Preview and Back Up Edits

  • Test Before Committing Changes: Run your sed commands without the -i option to preview the changes before modifying the file.
  • Always Create Backups: Use -i.bak to save a backup of the original file, just in case. For example:
sed -i.bak 's/foo/linux/g' file.txt

Ready to try more advanced techniques? The next examples introduce regular expressions, line targeting, and multi-file workflows so you can adapt sed to complex real-world edits.

Use Advanced sed Operations

Once you’ve mastered the basics, you can move on to sed‘s more advanced capabilities. Regular expressions let you match flexible patterns instead of literal strings, opening up possibilities like finding all IP addresses, standardizing date formats, or extracting specific data structures. Combined with line-specific operations and multi-file workflows, sed handles intricate text manipulation tasks efficiently.

Example 7: Replace Patterns with Regular Expressions

Regular expressions allow you to match patterns, not just literal strings. For instance, to replace all 3-digit numbers with the word number:

sed 's/\b[0-9]\{3\}\b/number/g' file.txt

Output:

number Foo foo foo
foo /bin/bash Ubuntu foobar number

This matches only 3-digit numbers (e.g., 123 or 456) and replaces them, leaving other numbers unaffected.

Example 8: Reuse Matched Text 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 's/\b[0-9]\{3\}\b/{&}/g' file.txt

Output:

{123} Foo foo foo
foo /bin/bash Ubuntu foobar {456}

Here, {&} inserts the matched number between the curly braces.

Example 9: Target Specific Lines for Substitutions

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 (lines 2 through 4; sed applies through the end of the file when the range exceeds total lines):
sed '2,4s/foo/linux/' file.txt

The sed command gives you fine-grained control over where replacements occur, avoiding unintended changes.

Example 10: Edit Many Files with find and sed

When working with large files or directories, combining sed with other tools like the find command or the grep command is useful. However, recursive operations require careful attention to avoid corrupting binary files or making unintended changes.

Before running any recursive sed operation, perform a dry run to see which files contain the search pattern and what the changes look like:

# List files containing the search term
grep -rl 'foo' .

# Preview the sed substitutions without writing changes
find . -type f -exec sed -n 's/foo/bar/gp' {} + | less

The following command modifies every file in the directory tree, including binaries, images, databases, and executables. Running it without proper filtering can corrupt system files or application data, so always preview first and restrict the scope to specific file types.

  • Recursive Search and Replace (USE WITH EXTREME CAUTION):
find . -type f -exec sed -i 's/foo/bar/g' {} +
  • Target Specific File Types (RECOMMENDED): Replace foo with bar only in .txt, .conf, and .cfg files:
find . -type f \( -name "*.txt" -o -name "*.conf" -o -name "*.cfg" \) -exec sed -i.bak 's/foo/bar/g' {} +

This safer approach limits changes to text files and creates backups automatically. Group the filename tests inside escaped parentheses so -type f applies to every branch.

Using grep to Target Only Matching Files: Search for files containing foo and replace it with bar, while creating backups:

grep -rIlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g'

This approach only modifies files that actually contain the search pattern, reducing the risk of unnecessary changes. The -Z and -0 flags handle filenames with spaces correctly.

Example 11: Stream Output with Unbuffered Mode

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.txt

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 (for example, 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.

Troubleshoot Common sed Issues

Even experienced users run into sed gotchas. Each issue below shows the symptom, cause, and fix so you can resolve problems quickly.

1. Only the First Match on Each Line Is Replaced

Symptom: You expect every occurrence to change, but only the first match per line is affected:

echo "foo bar foo baz foo" | sed 's/foo/REPLACED/'
REPLACED bar foo baz foo

Cause: Without the g flag, sed replaces only the first match on each line.

Fix: Add the g (global) flag:

echo "foo bar foo baz foo" | sed 's/foo/REPLACED/g'
REPLACED bar REPLACED baz REPLACED

2. sed Replaces Partial Words Unexpectedly

Symptom: Replacing man also changes manual and command:

echo "man reads the manual command" | sed 's/man/person/g'
person reads the personual compersond

Cause: Without word boundaries, sed matches the pattern inside any word.

Fix: Use \b word boundaries (GNU sed) to match whole words only:

echo "man reads the manual command" | sed 's/\bman\b/person/g'
person reads the manual command

3. GNU sed vs BSD sed (macOS) Differences

Syntax differences between GNU sed (Linux) and BSD sed (macOS) are a frequent source of errors. The most common conflicts:

In-place editing (-i): Running a GNU-style sed -i on macOS produces an error because BSD sed requires an argument after -i:

# This works on GNU sed but fails on BSD sed (macOS)
sed -i 's/old/new/g' file.txt
sed: 1: "file.txt": invalid command code f

Fix: On macOS, provide an empty string for no backup or a suffix for a backup:

# BSD sed (macOS) - no backup
sed -i '' 's/old/new/g' file.txt

# BSD sed (macOS) - with backup
sed -i '.bak' 's/old/new/g' file.txt

Extended regex (-E vs -r): GNU sed supports both -r and -E for extended regex. BSD sed only supports -E. Use -E for cross-platform scripts.

Always check your system’s man sed page for specifics. When in doubt, use -E instead of -r for extended regex portability.

4. “sed: -i may not be used with stdin” Error

Symptom: Piping output to sed -i fails:

cat file.txt | sed -i 's/old/new/g'
sed: -i may not be used with stdin

Cause: The -i flag edits files directly and cannot operate on piped input.

Fix: Redirect the output to a new file instead:

some_command | sed 's/old/new/g' > output_file.txt

Verify: Confirm the output file contains the expected changes:

head output_file.txt

5. Avoid Accidental sed File Modification

Running sed -i with a wrong pattern can silently corrupt a file. Always preview changes first:

# Preview - prints changes to terminal without modifying the file
sed 's/old/new/g' config.conf

# Apply with backup - creates config.conf.bak before writing
sed -i.bak 's/old/new/g' config.conf

Verify: Compare the backup and modified file to confirm only the intended changes were made:

diff config.conf.bak config.conf

6. Using sed on Binary Files

sed is designed for text files. Using it on binary files (like images or executables) can corrupt them silently. If you accidentally run sed -i against a binary, the file may become unusable with no error message.

Fix: Use the file command to check a file’s type before editing, and use tools like xxd or hexedit for binary file manipulation:

file myapp
myapp: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked

Combine sed with Other Text-Processing Commands

The sed command works well on its own, but combining it with other Linux text-processing commands extends its reach. Here are complementary tools with practical examples:

  • grep: Search for patterns in files and filter text before or after sed processing. Example: grep -rIlZ "ERROR" -- *.log | xargs -0 sed -i.bak 's/ERROR/WARN/g' finds only the log files that contain the string (skipping binaries) and updates them safely.
  • 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 from log files then transforms paths in the output.
  • tr: Translate or delete characters for simple character-level transformations. Example: cat config.ini | tr -d '\r' | sed 's/^#//g' removes Windows line endings then strips comment markers.
  • cut: Extract sections from lines of text based on delimiters or character positions. Example: cut -d':' -f1,7 /etc/passwd | sed 's|/bin/bash|/bin/zsh|g' extracts username and shell fields then updates default shells.
  • sort: Sort lines of text before processing with sed. Example: sort access.log | sed -n '/ERROR/p' sorts log entries then extracts only error lines for analysis.
  • uniq: Remove or identify duplicate lines in processed output. Example: sed 's/^[[:space:]]*//' file.txt | sort | uniq -c strips leading whitespace, sorts lines, and counts 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.
  • split: Break large files into smaller chunks for parallel sed processing. Example: split -l 10000 large.log chunk_ && for f in chunk_*; do sed -i 's/old/new/g' "$f"; done splits a log file and applies replacements to each chunk.

Combining these commands with sed gives you a versatile text-processing toolkit for scripting, log analysis, and configuration management.

FAQ: sed Find and Replace

How do I replace a string in multiple files with sed?

Use find to locate files and pipe them to sed. For example, find . -type f -name "*.conf" -exec sed -i.bak 's/old/new/g' {} + replaces old with new in all .conf files under the current directory. Always use -i.bak to create backups when editing multiple files.

What is the difference between sed -i and sed -i.bak?

Both edit the file in place. sed -i modifies the file directly with no backup, while sed -i.bak saves the original as filename.bak before applying changes. On macOS (BSD sed), you must write -i '' for no backup or -i '.bak' with a space before the suffix.

Can sed replace newline characters?

Yes, but sed processes one line at a time by default, so newlines require special handling. Use the N command to pull the next line into the pattern space, then substitute with sed ':a;N;$!ba;s/\n/ /g' file.txt to join all lines into one by replacing every newline with a space.

Why does sed only replace the first match on each line?

By default, the s (substitute) command replaces only the first match per line. Add the g flag to replace all occurrences: sed 's/old/new/g' file.txt.

Conclusion: Master sed Find and Replace

The sed command turns repetitive text edits into one-liner operations. From basic string substitution to regex-powered pattern matching and multi-file workflows with find and grep, you now have the tools to handle any find-and-replace task. For deeper coverage, consult the official GNU sed manual.

Found this guide useful?

Support LinuxCapable to keep tutorials free and up to date.

Buy me a coffee Buy me a coffee

Before commenting, please review our Comments Policy.
Formatting tips for your comment

You can use basic HTML to format your comment. Useful tags currently allowed:

You type Result
<code>command</code> command
<strong>bold</strong> bold
<em>italic</em> italic
<a href="URL">link</a> link
<blockquote>quote</blockquote> quote block

Leave a Comment

We read and reply to every comment - let us know how we can help or improve this guide.

Let us know you are human: