sed Command in Linux with Examples

The sed command in Linux is a stream editor that transforms text from files or pipelines without opening an editor. Unlike traditional editors that load entire files into memory and require interactive input, sed processes text line by line, applying commands you specify and outputting the result instantly. This design makes it perfect for automated text processing in scripts, data pipelines, and one-off command-line tasks where speed and precision matter.

This guide covers everything from installing GNU sed on minimal images to understanding the pattern and hold space buffers, applying address ranges, scripting with loops and branching, and chaining sed with other Unix tools for real-world automation. Follow along to practice selective printing, deletions, insertions, file reads and writes, multi-line operations, and reusable sed scripts that handle logs, CSV data, configuration files, and deployment workflows.

Why the sed Command Matters

Sed slips into everyday workflows because it reads from pipelines, respects automation, and works reliably across distributions without extra tooling. It also delivers far more than basic substitutions, handling selective printing, line insertion, multi-line transformations, and file I/O in the same lightweight binary.

  • System administrators extract targeted log entries, filter configuration snippets, renumber documentation, and automate bulk edits across sprawling directories.
  • Developers wire sed into build pipelines to inject version strings, strip comments before deployment, or reshape configuration templates during packaging.
  • Data analysts chain sed with other CLI tools to clean CSV exports, normalize delimiters, and isolate fields without reaching for heavier scripting languages.

If you specifically need in-depth coverage of finding and replacing strings in files, including handling special characters, working with delimiters, and troubleshooting cross-platform differences, see our dedicated sed find and replace guide. This article focuses on the broader sed command capabilities: printing specific lines, deleting patterns, inserting and appending text, working with address ranges, multi-line operations, hold space and pattern space manipulation, reading and writing files, and building reusable sed scripts for complex automation tasks.

Understand the sed Command

If you are new to sed, think of it as a command-line text processor that reads input line by line, applies transformation rules you specify, and outputs the result. Unlike opening a file in an editor, sed processes streams of text, making it perfect for pipelines where data flows from one command to another without creating temporary files.

Basic Syntax

Specifically, the basic syntax follows this pattern:

sed [OPTIONS] 'COMMAND' [INPUT-FILE]

Breaking down each component:

  • OPTIONS: Flags that modify sed’s behavior, such as -i for in-place editing, -n for suppressing automatic output, or -E for extended regular expressions. These are optional and can be combined (e.g., -n -i.bak).
  • COMMAND: The transformation you want to apply, wrapped in single quotes to protect it from shell interpretation. Commands can be simple like 'd' to delete lines, or complex like 's/old/new/g' for global substitution. You can chain multiple commands with semicolons: 's/foo/bar/; /error/d'.
  • INPUT-FILE: The file to process. If omitted, sed reads from standard input (stdin), allowing you to pipe data from other commands like cat file.txt | sed 's/foo/bar/' or curl https://example.com | sed '/ads/d'.

How sed Processes Text

Sed operates using two buffers that determine how text flows through the editor:

  • Pattern space: The working buffer where sed stores the current line being processed. Every sed command you write operates on the pattern space by default. When sed reads a new line, it replaces the pattern space content with that line (unless you use commands like N that append to it).
  • Hold space: A secondary storage buffer that persists between lines. You can copy or exchange data between pattern space and hold space using commands like h (hold), g (get), and x (exchange). This enables complex operations like reversing files, accumulating data across lines, or implementing conditional logic.

Workflow Cycle

In general, the typical sed workflow follows this cycle:

  1. Read a line from input into the pattern space
  2. Execute commands on the pattern space (substitute, delete, transform, etc.)
  3. Print the pattern space (unless -n suppresses it or a command deletes it)
  4. Move to the next line and repeat

For instance, sed 's/Linux/Unix/' file.txt reads file.txt line by line, replaces the first occurrence of “Linux” with “Unix” on each line, and prints the result to your terminal without changing the original file. The pattern space holds one line at a time, the substitution command modifies it, and sed automatically prints the modified line before moving to the next input line.

In addition, here are the most useful options and commands organized by task:

Sed Command Reference Table

Text Substitution

TaskOption/CommandWhat It Does
Replace first match per lines/pattern/replacement/Substitutes the first occurrence of “pattern” with “replacement” on each line
Replace all matches on each lines/pattern/replacement/gThe g flag makes substitution global, replacing every occurrence

Deletion Operations

TaskOption/CommandWhat It Does
Delete matching lines/pattern/dRemoves entire lines that contain “pattern”
Delete specific line numbers'3d' or '5,10d'Deletes line 3 or lines 5 through 10
Delete blank lines'/^$/d'Removes all empty lines from output

Printing and Output Control

TaskOption/CommandWhat It Does
Print specific lines-n '5p' or -n '10,20p'Prints only line 5 or lines 10 through 20 (requires -n flag)
Print matching lines-n '/pattern/p'Shows only lines containing “pattern” (similar to grep)
Suppress automatic output-nOnly prints lines when explicitly told with the p command

Insert and Append

TaskOption/CommandWhat It Does
Insert text before a line/pattern/i\textInserts “text” before lines matching “pattern”
Append text after a line/pattern/a\textAppends “text” after lines matching “pattern”

Line Addressing

TaskOption/CommandWhat It Does
Apply to specific line'5s/old/new/'Substitutes only on line 5
Apply to range'10,20s/old/new/'Substitutes on lines 10 through 20
Apply to pattern range'/start/,/end/d'Deletes lines from first “start” match to first “end” match
Negate address'/pattern/!d'Deletes all lines not matching “pattern”

Multi-line Operations

TaskOption/CommandWhat It Does
Append next line to pattern spaceNReads next line and appends to current pattern space with newline
Print first line of pattern spacePPrints up to first newline in pattern space (useful with N)
Delete first line of pattern spaceDDeletes up to first newline and restarts the cycle without reading a new line

Hold Space Operations

TaskOption/CommandWhat It Does
Copy pattern space to hold spacehOverwrites hold space with pattern space content
Append pattern space to hold spaceHAppends pattern space to hold space with newline separator
Copy hold space to pattern spacegOverwrites pattern space with hold space content
Append hold space to pattern spaceGAppends hold space to pattern space with newline separator
Exchange buffersxSwaps pattern space and hold space contents

File Operations

TaskOption/CommandWhat It Does
Edit files in place-iModifies the original file instead of printing to stdout
Read file and insertr filenameReads content from a file and inserts it after the current line
Write to filew filenameWrites pattern space to a file (appends if the file exists)
Use script file-f script.sedReads sed commands from a file instead of the command line

Advanced Features

TaskOption/CommandWhat It Does
Chain multiple commands-e 'cmd1' -e 'cmd2'Applies multiple transformations in sequence
Use extended regex-EEnables extended regular expressions (less escaping needed)
Quit processingqExits sed immediately after the current line
Transform charactersy/abc/xyz/Transliterates characters (similar to the tr command)
Print line numbers=Prints the current line number before the line content

Consequently, the “suppresses automatic output” behavior of -n means sed won’t print every line by default. Normally, sed prints all input lines (whether changed or not), but -n turns off this behavior so you control exactly what gets printed using the p command. This is essential when you want to extract specific lines instead of transforming the entire file.

Install sed on Popular Linux Distributions

GNU sed ships with virtually every mainstream Linux distribution, but minimal containers or stripped-down images may omit it. Verify availability first, then install the package that adds the full-featured GNU sed binary if it is missing.

Check whether sed is already present:

sed --version

If the command is not found, use 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

The package name is sed across these distributions, so the commands above install the GNU implementation that supports the features used throughout this guide.

Basic Examples of Sed Command in Linux

Example 1: Basic Text Substitution

Text substitution is sed’s most recognized operation, though far from its only capability. This example demonstrates the simplest form before moving to sed’s broader feature set:

echo "Welcome to Linux" | sed 's/Linux/Unix/'

Output:

Welcome to Unix

For comprehensive coverage of find-and-replace operations including global substitution, case-insensitive matching, handling special characters, delimiter choices, and in-place editing with backups, see our dedicated sed find and replace guide which covers substitution operations in depth.

Example 2: Printing Specific Lines

Additionally, the -n option combined with the p command lets you extract specific lines without modifying them. This is useful when you need to view particular sections of log files, configuration files, or data exports.

First, display line 5 from a file:

sed -n '5p' /var/log/syslog

Next, pull lines 10 through 20:

sed -n '10,20p' /etc/services

Finally, show lines matching a pattern (similar to grep):

sed -n '/error/p' application.log

The -n flag suppresses sed’s default behavior of printing every line, so only lines explicitly marked with p appear in the output. Without -n, you would see all lines plus duplicates of the matched ones.

Example 3: Deleting Lines

In practice, when processing log files or data exports, you often need to remove lines matching specific patterns. Sed’s d command deletes lines from the output stream without modifying the source file.

To start, remove every line containing “debug”:

sed '/debug/d' application.log

Then clear any blank lines:

sed '/^$/d' messy-file.txt

After that, drop lines 5 through 10:

sed '5,10d' data.csv

Finally, cut everything from a specific marker to the end of the file:

sed '/START_OF_FOOTER/,$d' document.txt

The d command removes matched lines from the pattern space entirely, preventing them from reaching the output. The dollar sign ($) in address ranges represents the last line of the input.

Example 4: Inserting and Appending Text

Similarly, adding lines before or after specific patterns lets you inject headers into data files, add comments to configuration sections, or insert timestamps without manually editing each file.

Insert text before a pattern:

sed '/^database_settings/i\# Database Configuration' config.ini

Append text after a pattern:

sed '/^server {$/a\    # Server block configuration' nginx.conf

Insert multiple lines (using literal newlines):

sed '/pattern/i\First line\
Second line\
Third line' file.txt

The i command inserts before the matched line, while a appends after it. Both commands place the new text in the output stream without modifying the pattern space content of existing lines.

Example 5: Changing Text Case with Transform

Likewise, the y command transliterates characters, similar to the tr command. This is useful when normalizing data for comparisons, standardizing input formats, or preparing text for case-sensitive systems.

Convert lowercase to uppercase:

echo "hello world" | sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'

Output:

HELLO WORLD

Convert specific characters:

echo "a-b-c-d" | sed 'y/-/_/'

Output:

a_b_c_d

The y command maps each character in the first set to the corresponding character in the second set. Both sets must contain the same number of characters, and the transformation applies to every matching character in the pattern space.

Example 6: Printing Line Numbers

Similarly, the = command prints the current line number, which helps when debugging sed scripts, identifying line positions in large files, or creating numbered lists.

Print line numbers for all lines:

printf "apple\nbanana\ncherry\n" | sed '='

Output:

1
apple
2
banana
3
cherry

Print line numbers only for matching lines:

sed -n '/error/=' application.log

The = command outputs the line number on its own line before the pattern space content, so you see the number followed by the actual text on the next line.

Advanced Usage of the Sed Command in Linux

Example 7: Address Ranges and Line Selection

Moreover, sed’s addressing system lets you apply commands to specific lines, ranges of lines, or lines matching patterns. This precision is essential when editing configuration files where changes should only affect particular sections, or when processing log files where you need to extract or modify specific time ranges.

Target a specific line number

sed '3s/old/new/' file.txt

Operate on a range of line numbers

sed '10,20s/DEBUG/INFO/' application.log

Match a range defined by two patterns

sed '/<configuration>/,/<\/configuration>/s/enabled="false"/enabled="true"/' config.xml

Process from a specific line to end of file

sed '100,$d' large-file.txt

Negate an address

sed '/^#/!d' script.sh

This last example keeps only comment lines (those starting with #) by deleting everything else. The exclamation mark negates the address, so the delete command applies to all lines that don’t match the pattern.

Example 8: Multi-line Operations

Additionally, multi-line commands let you work with blocks of text instead of individual lines. This is crucial when processing data formats where logical units span multiple lines, such as configuration blocks, code functions, or data records split across lines.

Join lines into a single record

printf "line one\nline two\nline three\n" | sed 'N;s/\n/ /'

Output:

line one line two
line three

The N command appends the next line to the pattern space with a newline separator, then the substitution replaces that newline with a space. Sed processes pairs of lines this way, joining every two consecutive lines.

Collapse multiple blank lines

sed '/^$/{N;/^\n$/d;}' file-with-blank-lines.txt

Match patterns across line boundaries

printf "Error:\nConnection timeout\n" | sed 'N;s/Error:\nConnection/Error: Network connection/'

Output:

Error: Network connection timeout

Multi-line operations are particularly useful when reformatting code, merging continued lines in configuration files, or processing data exports where field values span multiple lines.

Example 9: Hold Space and Pattern Space

Furthermore, the hold space acts as a secondary buffer for storing data between lines. This enables complex transformations like reversing file order, accumulating data across multiple lines, or implementing conditional logic based on previous content.

Reverse the order of lines

printf "first\nsecond\nthird\n" | sed -n '1!G;h;$p'

Output:

third
second
first

This approach works by: (1) For all lines except the first, append hold space to pattern space with G, (2) Copy pattern space to hold space with h, (3) On the last line ($), print the accumulated result. Each new line gets prepended to the accumulated content in hold space, effectively reversing the order.

Detect consecutive duplicates

printf "apple\napple\nbanana\nbanana\nbanana\ncherry\n" | sed -n 'N;/^\(.*\)\n\1$/p;D'

The command reads two lines at a time, prints them when both lines match, and restarts the cycle so you only see consecutive duplicates once per pair.

Swap every two lines

printf "line1\nline2\nline3\nline4\n" | sed 'N;s/\(.*\)\n\(.*\)/\2\n\1/'

Output:

line2
line1
line4
line3

Hold space operations become essential when you need to maintain state across lines, such as tracking section headers, accumulating totals, or comparing current lines with previous ones.

Example 10: Reading and Writing Files

Additionally, sed can read content from external files and insert it into the output stream, or write portions of the pattern space to separate files. This enables powerful workflows like merging templates with data, splitting files based on patterns, or building files dynamically during processing.

Insert file content after matching lines

echo "This is a header." > header.txt
printf "Section 1\nContent here\nSection 2\nMore content\n" | sed '/^Section/r header.txt'

Output:

Section 1
This is a header.
Content here
Section 2
This is a header.
More content

The r command reads the entire file and inserts it after each line matching the pattern. This is useful for injecting common headers, footers, or template content at specific points.

Write matching lines to a separate file

sed -n '/ERROR/w errors.log' application.log

Split a file based on patterns

sed '/^INFO/w info.log
/^WARN/w warnings.log
/^ERROR/w errors.log' mixed.log

The w command appends the pattern space to the specified file. If the file doesn’t exist, sed creates it; if it exists, sed appends to it. This lets you filter and route different parts of input to different destinations in a single pass.

Example 11: Using Sed Script Files

Whenever sed commands become complex or you need to reuse the same transformations across multiple files, putting commands in a script file makes them easier to maintain and share. The -f option reads commands from a file instead of the command line.

Create a sed script file:

cat > cleanup.sed <<'EOF'
# Remove blank lines
/^$/d

# Remove comments
/^#/d

# Convert tabs to spaces
s/\t/    /g

# Trim trailing whitespace
s/[[:space:]]\+$//
EOF

Apply the script to a file:

sed -f cleanup.sed messy-config.txt

Script files support comments (lines starting with #) and can contain as many commands as needed, one per line. Commands in script files execute in sequence, just as if you chained them with semicolons on the command line.

Apply the same script to multiple files:

find . -name "*.conf" -exec sed -i.bak -f cleanup.sed {} +

This approach keeps your transformation logic in one place, making it easier to version control, document, and apply consistently across projects.

Example 12: Conditional Execution and Branching

Similarly, sed supports conditional execution using the b (branch) and t (test) commands. These let you create complex logic flows within sed scripts, implementing if-then-else patterns or loops without invoking a full scripting language.

Skip processing for comment lines:

sed '/^#/b; s/old/new/g' config.txt

This branches (jumps to the end of the script) for lines starting with #, effectively skipping the substitution command for comments.

Apply multiple substitutions until no more changes occur:

echo "aaabbbccc" | sed ':loop; s/aa/a/g; t loop'

Output:

abbbccc

The :loop creates a label, and t loop branches back to that label if the previous substitution succeeded. This creates a loop that keeps replacing aa with a until no more aa sequences exist.

Example 13: Quitting Early with q

In turn, the q command exits sed immediately after processing the current line. This improves performance when you only need to process the beginning of large files, such as extracting headers or stopping after finding a specific pattern.

Print only the first 10 lines (like head -10):

sed '10q' large-logfile.log

Stop processing after finding a pattern:

sed '/^ERROR/q' application.log

Extract everything up to a marker:

sed '/^---END OF HEADER---$/q' document.txt

The q command prints the current line (unless you use -n) and then exits immediately, saving time on large files by avoiding unnecessary processing of remaining content.

Practical Real-World Examples

Example 14: Processing Log Files

Because log file analysis often requires extracting specific entries, removing noise, or reformatting timestamps, sed handles these tasks efficiently without loading entire files into memory.

Begin by extracting only error and warning messages:

sed -n '/ERROR\|WARN/p' application.log

Next, remove debug and trace messages:

sed '/DEBUG\|TRACE/d' verbose.log > clean.log

Then isolate logs from a specific time range:

sed -n '/2025-11-06 14:00/,/2025-11-06 15:00/p' timestamped.log

Finally, add line numbers to error messages for easier debugging:

sed -n '/ERROR/{=;p;}' application.log | sed 'N;s/\n/: /'

Example 15: CSV and Data File Manipulation

Likewise, sed excels at cleaning and transforming CSV files or other delimited data formats. You can extract columns, reorder fields, or normalize inconsistent formatting without loading data into spreadsheet software.

Extract the second column from CSV data:

echo "Name,Age,City\nJohn,30,NYC\nJane,25,LA" | sed 's/^[^,]*,\([^,]*\).*/\1/'

Output:

Age
30
25

Remove the header row from CSV:

sed '1d' data.csv > data-no-header.csv

Convert comma-separated to tab-separated:

sed 's/,/\t/g' data.csv > data.tsv

Remove quotes from quoted CSV fields:

sed 's/"//g' quoted.csv > unquoted.csv

Example 16: Configuration File Updates

For operations teams, automated configuration management relies on tools like sed to modify settings without manual editing. This is especially valuable when provisioning servers, updating application settings during deployment, or maintaining consistent configurations across environments.

Change a configuration value:

sed -i 's/^max_connections = .*/max_connections = 200/' postgresql.conf

Enable a commented-out setting:

sed -i 's/^# *\(listen_addresses\)/\1/' postgresql.conf

Update multiple related settings in one pass:

sed -i -e 's/old_server/new_server/' \
       -e 's/port=3306/port=3307/' \
       -e 's/timeout=30/timeout=60/' database.ini

Add a new setting after a specific section header:

sed -i '/^\[database\]$/a\new_option = value' config.ini

Example 17: Code and Documentation Processing

On macOS or other BSD-based systems, sed -i expects a backup suffix. Use sed -i '' 's/pattern/replacement/' file to edit in place without leaving backup files, or provide an explicit suffix such as -i .bak.

Developers frequently use sed in build pipelines to inject version strings, strip comments for production code, or transform documentation formats. These operations integrate seamlessly into automated workflows.

Strip single-line comments from code:

sed '/^[[:space:]]*\/\//d' source.js > clean-no-comments.js

This removes standalone // comment lines without touching URLs or other inline content, which is safer for source files that embed strings like https://.

Trim trailing inline comments that follow code (assuming your style inserts a space before the comment):

sed -E 's#[[:space:]]+//.*$##' source.js > clean-inline-comments.js

This expression only removes // sequences that are preceded by whitespace, so strings and protocol prefixes stay intact. Adjust the pattern if your codebase formats inline comments differently.

Inject build version into source files:

VERSION="2.4.1"
sed -i "s/VERSION_PLACEHOLDER/$VERSION/" version.h

Convert Markdown headers to HTML:

sed -E 's/^## (.*)$/

\1<\/h2>/' document.md

Extract function definitions from source code:

sed -n '/^def /p' python_script.py

Example 18: System Administration Tasks

In daily administration, system administrators leverage sed for bulk user management, automated system configuration updates, and processing command output from other tools in complex pipelines.

Extract usernames from /etc/passwd:

sed 's/:.*$//' /etc/passwd

Find users with specific shell:

sed -n '/\/bin\/bash$/p' /etc/passwd

Format disk usage output for easier reading:

df -h | sed '1d' | sed 's/\([0-9]\+\)%/[\1%]/'

Generate hosts file entries from a list:

cat server-list.txt | sed 's/^/192.168.1./' | sed 's/$/.example.com/'

Example 19: Combining Sed with Other Commands

Ultimately, sed’s true power emerges when combined with other Unix tools in pipelines. These combinations let you build sophisticated text processing workflows that would require substantial code in traditional scripting languages.

Find and clean recent error logs:

find /var/log -name "*.log" -mtime -1 -exec sed -n '/ERROR/p' {} + | sort | uniq

Process web server logs to extract IP addresses:

cat access.log | sed 's/^\([^ ]*\) .*/\1/' | sort | uniq -c | sort -rn | head -10

The substitution stores the first space-delimited field, so both dotted IPv4 addresses and colon-separated IPv6 addresses remain intact before sorting and counting.

Clean up process list output:

ps aux | sed '1d' | sed 's/  \+/ /g' | cut -d' ' -f1,11

Extract and format package versions:

dpkg -l | sed -n '/^ii/p' | sed 's/  \+/ /g' | cut -d' ' -f2,3

Conclusion

Overall, the sed command provides fast, scriptable text transformations for virtually any text processing task in Linux. By understanding pattern space and hold space buffers, mastering address ranges and multi-line operations, using read and write commands for file manipulation, leveraging sed script files for complex reusable workflows, and knowing how to chain sed with other Unix tools in pipelines, you can confidently automate text processing tasks that range from simple line deletions to complex multi-file transformations. For in-depth coverage of text substitution operations, see our companion guide on finding and replacing strings with sed.

Leave a Comment