---
title: "Sed"
description: "Complete sed reference with substitution, addressing, deletion, insertion, transformations, in-place editing, and real-world examples for text manipulation"
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/cheatsheets/sed
---

# Sed

This comprehensive sed reference covers everything from basic text substitution to advanced scripting techniques. Learn how to use sed for powerful text processing, file editing, and automation with practical examples and best practices.

## Getting Started

Introduction to sed and basic concepts

### What is Sed

Understanding sed and its capabilities as a stream editor

**Keywords:** sed, stream editor, text processing, transformation, automation

#### Sed overview and basic concepts

```bash
# Sed stands for: Stream Editor
# Processes text line by line, applying commands to matching lines

# Basic syntax: sed [options] 'command' file
# Most common: sed 's/pattern/replacement/' file

# Key features:
# - Non-interactive text transformations
# - Pattern matching with regular expressions
# - Substitution, deletion, insertion, transformation
# - Process files in-place or to stdout
# - Powerful scripting capabilities
# - Efficient stream processing
```

_exec_
```bash
echo -e "apple\nbanana\ncherry" | sed 's/apple/orange/'
```

_output_
```bash
orange
banana
cherry
```

Sed reads input line by line, applies the substitution command to match patterns, and outputs the result.

- Sed is line-oriented; processes one line at a time
- Pattern/replacement is most common use case
- Non-destructive by default (modifies stdout, not file)
- Use -i flag for in-place file modification

#### Sed vs other text processing tools

```bash
# Compare sed with similar tools:
# sed: Stream transformations (substitution, deletion, etc.)
# awk: Full text processing language with patterns and fields
# grep: Search for patterns in lines (filtering)
# perl: Programming language for text manipulation

# Use sed when you need:
# - Simple text transformations
# - Substitutions and replacements
# - Deletion of lines or parts
# - Regular find-and-replace operations
# - Lightweight processing without awk/perl
```

_exec_
```bash
echo -e "hello world\ntest string" | sed 's/world/universe/; s/test/sample/'
```

_output_
```bash
hello universe
sample string
```

Sed excels at simple but powerful text transformations using substitution and command chaining.

- Sed is lighter than awk/perl for simple operations
- Faster processing for large files
- More portable across Unix systems
- CLI-friendly for bash scripting

**Best practices:**

- Use single quotes to prevent shell expansion
- Test commands on sample data before running on production files
- Use -E for consistent extended regex syntax
- Combine multiple commands with semicolons

**Common errors:**

- **Unterminated s command**: Ensure delimiters are properly matched and escaped

### Installation and Setup

Installing sed and verifying functionality

**Keywords:** install, setup, version, verify, test

#### Verify sed installation

```bash
# Check if sed is installed
which sed

# Display sed version
sed --version

# Show sed help
sed --help | head -20
```

_exec_
```bash
sed --version | head -3
```

_output_
```bash
GNU sed, version 4.9
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
```

Sed is typically pre-installed on Linux. Verify version with --version flag.

- Sed is standard on all Unix-like systems
- GNU sed and BSD sed have minor differences
- GNU sed has more features and extensions
- Most scripts work on both versions

#### Install sed on different systems

```bash
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y sed

# CentOS/RHEL
sudo yum install -y sed

# macOS (comes with BSD sed)
brew install gnu-sed  # Installs GNU sed as gsed

# Alpine Linux
apk add sed

# Arch Linux
sudo pacman -S sed
```

_exec_
```bash
which sed && sed --version | head -1
```

_output_
```bash
/usr/bin/sed
GNU sed, version 4.9
```

Sed is universally available on Linux. macOS users may prefer GNU sed for compatibility.

- GNU sed has more robust features
- BSD sed works for basic operations
- macOS comes with BSD sed by default
- GNU sed available as gsed on macOS

**Best practices:**

- Verify sed is available before scripts
- Use absolute paths in production scripts
- Check version for platform compatibility

**Common errors:**

- **sed: command not found**: Install sed using package manager

## Basic Substitution

Simple text replacements and substitution patterns

### Simple Replacements

Basic substitution with literal text

**Keywords:** substitution, replace, s command, pattern, replacement

#### Simple text substitution

```bash
# Basic substitution syntax: s/pattern/replacement/
# Replace first occurrence on each line

# Simple example
sed 's/old/new/' file.txt

# Replace on specific line
sed '3s/foo/bar/' file.txt

# Multiple substitutions
sed 's/a/b/; s/c/d/' file.txt
```

_exec_
```bash
echo -e "hello world\nhello there" | sed 's/hello/hi/'
```

_output_
```bash
hi world
hi there
```

The s command (substitution) replaces the first occurrence of pattern with replacement on each line.

- Only replaces first occurrence per line by default
- Pattern can be literal text or regex
- Original file is not modified unless using -i
- Delimiters (/) can be any character

#### Using different delimiters

```bash
# Use different delimiters for readability
# Useful when pattern contains /

# Colon delimiter
sed 's:pattern:replacement:' file.txt

# Pipe delimiter
sed 's|pattern|replacement|' file.txt

# Hash delimiter
sed 's#pattern#replacement#' file.txt

# Useful with paths
sed 's|/old/path|/new/path|' file.txt
```

_exec_
```bash
echo "/usr/local/bin" | sed 's|/local||'
```

_output_
```bash
/usr/bin
```

Using alternative delimiters prevents escaping forward slashes in patterns.

- Any character can be delimiter (avoid regex metacharacters)
- Improves readability with paths
- Reduces escaping requirements

**Best practices:**

- Quote patterns to prevent shell interpretation
- Test on small file first
- Use appropriate delimiter for pattern content

**Common errors:**

- **Unterminated s command**: Ensure matching delimiters

### Global Replacements

Replace all occurrences using g flag

**Keywords:** global, g flag, all occurrences, replacements

#### Global replacement flag

```bash
# g flag replaces all occurrences on each line
# Syntax: s/pattern/replacement/g

# Replace all
sed 's/foo/bar/g' file.txt

# Global with different delimiter
sed 's|pattern|replacement|g' file.txt

# Multiple substitutions, all global
sed 's/a/b/g; s/c/d/g' file.txt
```

_exec_
```bash
echo "cat dog cat bird cat" | sed 's/cat/mouse/g'
```

_output_
```bash
mouse dog mouse bird mouse
```

The g flag replaces all occurrences of pattern on each line, not just the first.

- Without g flag, only first occurrence is replaced
- g flag is most common use case
- Works with case-insensitive flag (i)
- Can be combined with other flags

#### Partial global replacement

```bash
# Replace only 2nd and subsequent occurrences
# Syntax: s/pattern/replacement/2g

sed 's/the/THE/2g' file.txt

# Replace starting at 3rd occurrence
sed 's/a/A/3g' file.txt

# Replace 2nd occurrence only
sed 's/foo/bar/2' file.txt
```

_exec_
```bash
echo "the cat in the hat" | sed 's/the/THE/2g'
```

_output_
```bash
the cat in THE hat
```

Numeric flags target specific occurrences; 2g means 2nd and following.

- Number specifies starting occurrence
- 2g means 2nd, 3rd, 4th, etc.
- Without g, only that specific occurrence replaced

**Best practices:**

- Use g flag for comprehensive replacements
- Consider case-insensitivity with i flag
- Test pattern first to ensure correct matches

**Common errors:**

- **Matches not being replaced**: Use g flag or check pattern matches correctly

### Flags and Options

Substitution flags and command-line options

**Keywords:** flags, options, s command flags, parameters, modifiers

#### Substitution flags

```bash
# Common substitution flags:
# g = global (all occurrences)
# i = case-insensitive
# p = print matched line
# e = execute replacement as shell command
# number = replace only nth occurrence

# Case-insensitive replacement
sed 's/hello/hi/i' file.txt

# Print matching lines with -n
sed -n 's/pattern/replacement/p' file.txt

# Combine flags
sed 's/HELLO/hi/gi' file.txt  # global + case-insensitive
```

_exec_
```bash
echo -e "Hello\nHELLO\nhello" | sed 's/hello/hi/gi'
```

_output_
```bash
hi
hi
hi
```

Multiple flags can be combined; i makes pattern case-insensitive, g replaces all.

- Flags can be combined (gip, etc.)
- Flag order doesn't matter for most flags
- g flag most useful with others
- p flag useful with -n option

#### Command-line options

```bash
# sed command-line options:
# -n = suppress automatic printing (quiet mode)
# -e = specify script
# -f = read script from file
# -i = in-place file editing
# -E/-r = use extended regular expressions

# Quiet mode: only print matched lines
sed -n 's/pattern/replacement/p' file.txt

# Extended regex
sed -E 's/(old)(text)/\2-\1/' file.txt

# Multiple scripts
sed -e 's/a/b/' -e 's/c/d/' file.txt
```

_exec_
```bash
echo -e "match1\nnomatch\nmatch2" | sed -n 's/match/MATCH/p'
```

_output_
```bash
MATCH1
MATCH2
```

The -n option suppresses default line printing; p flag prints only lines with substitutions.

- -n is combination of quiet mode and p flag
- Very useful for filtering by pattern
- Different from grep; modifies matched portion

**Best practices:**

- Use -E for consistency with modern regex syntax
- Use -n with p for filtering matches
- Test regex patterns before in-place editing

**Common errors:**

- **Invalid command line**: Verify option syntax and flag order

## Addressing and Ranges

Target specific lines or ranges of lines

### Line-based Addressing

Target operations to specific line numbers

**Keywords:** addressing, line numbers, line range, specific lines

#### Address specific lines

```bash
# Operate on specific line number
# Syntax: sed 'LineNums command' file

# Line 1 only
sed '1s/foo/bar/' file.txt

# Line 3 only
sed '3s/old/new/' file.txt

# Last line ($)
sed '$s/end/END/' file.txt

# Lines 1-5
sed '1,5s/a/b/' file.txt
```

_exec_
```bash
echo -e "line1\nline2\nline3\nline4" | sed '2s/line/LINE/'
```

_output_
```bash
line1
LINE2
line3
line4
```

Line numbers target specific lines; 2 means line 2 only.

- Line numbers start at 1
- $ is last line
- Multiple lines use comma: 1,5
- Range is inclusive

#### Line ranges and intervals

```bash
# Range syntax: startLine,endLine command

# Lines 5 to 10
sed '5,10s/old/new/' file.txt

# Lines 1 to last line
sed '1,$s/a/b/' file.txt

# Every 5th line starting at line 1
sed '1~5d' file.txt  # GNU sed only

# From specific line to end
sed '100,$s/text/TEXT/' file.txt
```

_exec_
```bash
seq 1 6 | sed '2,5s/.*/[LINE]/'
```

_output_
```bash
1
[LINE]
[LINE]
[LINE]
[LINE]
6
```

Range 2,5 targets lines 2 through 5 inclusive.

- Ranges are inclusive on both ends
- 1~5 means every 5th line (GNU sed)
- Intervals: line~step (GNU sed extension)

**Best practices:**

- Test line addresses on small files
- Use ranges for batch operations
- Remember $ for last line

**Common errors:**

- **Wrong lines modified**: Verify line numbers; remember 1-based indexing

### Regex-based Addressing

Target lines matching regular expressions

**Keywords:** regex, pattern matching, conditional, search-based

#### Target lines by pattern

```bash
# Address lines matching pattern
# Syntax: sed '/pattern/command' file

# Lines containing "error"
sed '/error/s/old/new/' file.txt

# Lines starting with #
sed '/^#/d' file.txt

# Lines ending with semicolon
sed '/;$/s/;//' file.txt

# Case-insensitive pattern
sed '/ERROR/Iy s/msg/MESSAGE/' file.txt
```

_exec_
```bash
echo -e "start\nmiddle\nend" | sed '/mid/s/./X/'
```

_output_
```bash
start
Xiddle
end
```

/mid/ matches lines containing "mid" string; operation applies only to matched lines.

- Pattern is regex; can use anchors
- Matches any line containing pattern substring
- Case-sensitive by default
- I flag makes pattern case-insensitive

#### Range by regex patterns

```bash
# Range from start pattern to end pattern
# Syntax: /startPattern/,/endPattern/command

# Delete from "start" to "end"
sed '/start/,/end/d' file.txt

# Substitute in pattern ranges
sed '/BEGIN/,/END/s/old/new/' file.txt

# Print only section between patterns
sed -n '/start/,/stop/p' file.txt

# Multiple ranges
sed '/foo/,/bar/d; /baz/,/qux/d' file.txt
```

_exec_
```bash
echo -e "a\nSTART\nb\nc\nEND\nd" | sed '/START/,/END/s/./X/'
```

_output_
```bash
a
X
X
X
X
d
```

Range /START/,/END/ targets all lines from pattern to pattern inclusive.

- Ranges inclusive on both ends
- Patterns are regex patterns
- Single occurrence per file for regex ranges
- Useful for multi-line operations

**Best practices:**

- Escape special regex characters
- Test patterns on sample data
- Use anchors for clarity

**Common errors:**

- **Pattern not matching**: Verify regex syntax; remember case sensitivity

### Range Specifications

Combining addresses for flexible targeting

**Keywords:** ranges, combinations, addressing, complex patterns

#### Step addressing

```bash
# Every nth line (GNU sed)
# Syntax: first~step

# Every 2nd line starting from line 1
sed '1~2d' file.txt

# Every 3rd line starting from line 2
sed '2~3s/x/y/' file.txt

# Every 5th line
sed '0~5d' file.txt  # 5, 10, 15, 20...

# Process in chunks
sed '1~10s/^/> /' file.txt  # prefix every 10th
```

_exec_
```bash
seq 1 10 | sed '1~3s/^/LINE:/'
```

_output_
```bash
LINE:1
2
3
LINE:4
5
6
LINE:7
8
9
LINE:10
```

1~3 means line 1, then every 3rd line after (1, 4, 7, 10...).

- Syntax: first~step (GNU sed extension)
- Step interval starting from first line
- Very useful for pattern-based processing
- Not available in BSD sed

#### Negation and exclusion

```bash
# Negate address with !
# Apply command to all lines EXCEPT matched

# Delete all lines except those matching
sed '/pattern/!d' file.txt

# Modify all lines except specified range
sed '10,20!d' file.txt

# Apply to all non-matching lines
sed '/^#/!s/old/new/' file.txt

# Keep only non-empty lines
sed '/^$/!s/a/b/' file.txt
```

_exec_
```bash
echo -e "keep\ndelete\nkeep" | sed '/keep/!d'
```

_output_
```bash
keep
keep
```

The ! operator inverts the address; operation applies to non-matching lines.

- ! means NOT or inverse
- Keep lines matching pattern by deleting non-matches
- Can use with line numbers or regex

**Best practices:**

- Use step addressing for large files
- Test negation patterns carefully
- Combine addresses for powerful filtering

**Common errors:**

- **Wrong lines processed**: Verify address syntax and order

## Deletion and Insertion

Delete, append, insert, and change lines

### Delete Commands

Remove lines from output

**Keywords:** delete, d command, remove, lines

#### Delete lines with d command

```bash
# d command deletes matching lines
# Syntax: [address]d

# Delete specific line
sed '5d' file.txt

# Delete pattern-matching lines
sed '/error/d' file.txt

# Delete range of lines
sed '10,20d' file.txt

# Delete empty lines
sed '/^$/d' file.txt

# Delete lines starting with #
sed '/^#/d' file.txt
```

_exec_
```bash
echo -e "line1\nline2\nline3\nline4" | sed '2d'
```

_output_
```bash
line1
line3
line4
```

The d command deletes (removes) the specified line from output.

- d stops processing line; next line is read
- Original file not modified (unless -i used)
- Pattern matching deletes all matching lines
- Useful for filtering

#### Delete with pattern ranges

```bash
# Delete line ranges
sed '/start/,/end/d' file.txt

# Delete first 10 lines
sed '1,10d' file.txt

# Delete last line
sed '$d' file.txt

# Delete all lines except first
sed '1!d' file.txt

# Keep only lines matching pattern
sed '/keep/!d' file.txt
```

_exec_
```bash
seq 1 5 | sed '2,4d'
```

_output_
```bash
1
5
```

Range 2,4d deletes lines 2 through 4 inclusive.

- Range includes both start and end lines
- d with ! inverts; deletes non-matching lines
- $ = last line

**Best practices:**

- Test deletion patterns first
- Use negation (!) to keep matching lines
- Verify addresses before deletion

**Common errors:**

- **All lines deleted**: Check addressing; consider using ! for inverse

### Append and Insert

Add lines before or after matched lines

**Keywords:** append, insert, a command, i command, add lines

#### Append and insert commands

```bash
# a = append (add after line)
# i = insert (add before line)
# Syntax: [address]a\text or [address]i\text

# Append text after line 3
sed '3a\NEW LINE' file.txt

# Insert text before line 5
sed '5i\INSERTED' file.txt

# Append after pattern match
sed '/pattern/a\APPENDED TEXT' file.txt

# Insert before first line
sed '1i\HEADER' file.txt

# Append to last line
sed '$a\FOOTER' file.txt
```

_exec_
```bash
echo -e "line1\nline2" | sed '2a\APPENDED'
```

_output_
```bash
line1
line2
APPENDED
```

The a command appends (adds) a new line after the matched line.

- i inserts before; a appends after
- Text must follow backslash on same line
- Multiline text requires backslash continuation
- No substitution in appended text

#### Multiline append and insert

```bash
# Multiple lines with continuation
sed '3a\line1\
line2\
line3' file.txt

# Using printf for readability
sed '2a\'"$(printf 'line1\nline2')"'' file.txt

# Append blank line
sed '/pattern/a\' file.txt

# Insert multiple blocks
sed '/start/i\BEGIN\nCONTENT' file.txt
```

_exec_
```bash
echo "middle" | sed 'i\START' | sed 'a\END'
```

_output_
```bash
START
middle
END
```

Chaining insert (i) and append (a) commands adds multiple lines.

- Each line continuation needs backslash
- Piping sed commands adds processing overhead
- Better to use multiple -e flags

**Best practices:**

- Test insert/append patterns first
- Use -e for multiple commands instead of pipes
- Quote multiline text carefully

**Common errors:**

- **Syntax error**: Verify backslash escaping in multiline text

### Change Command

Replace entire lines with new content

**Keywords:** change, c command, replace line, substitution

#### Change lines with c command

```bash
# c = change (replace entire line)
# Syntax: [address]c\text

# Change line 3
sed '3c\NEW LINE' file.txt

# Change pattern-matching lines
sed '/pattern/c\REPLACEMENT' file.txt

# Change range of lines
sed '5,10c\CHANGED' file.txt

# Change first occurrence of pattern
sed '/error/c\ERROR HANDLED' file.txt
```

_exec_
```bash
echo -e "line1\nline2\nline3" | sed '2c\CHANGED'
```

_output_
```bash
line1
CHANGED
line3
```

The c command replaces the entire matched line with the specified text.

- Entire line is replaced, not just pattern
- Range with c replaces all with single line
- Pattern matching replaces each matching line
- Original line content is lost

#### Change with ranges

```bash
# Range with change: all lines become one
sed '5,10c\SECTION REPLACED' file.txt

# Pattern range change
sed '/begin/,/end/c\BLOCK' file.txt

# Selective change with condition
sed '/^old/c\new' file.txt

# Preserve format with change
sed '/find/c\  replaced' file.txt  # indentation
```

_exec_
```bash
seq 1 5 | sed '2,4c\[REMOVED]'
```

_output_
```bash
1
[REMOVED]
5
```

Range 2,4c replaces all lines in range with single line.

- Range replaced with one line (unlike delete)
- Useful for removing blocks
- Preserves position in sequence

**Best practices:**

- Use change for complete line replacement
- Test patterns before changing production files
- Reserve for cases where entire line changes

**Common errors:**

- **Range behavior unexpected**: Remember range replaced with single line

## Text Transformation

Advanced text transformation operations

### Transliteration (y command)

Character-by-character translation

**Keywords:** transliteration, y command, character mapping, translation

#### Transliteration with y command

```bash
# y command: transliteration (character mapping)
# Syntax: y/source-chars/dest-chars/

# Convert lowercase to uppercase
sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' file.txt

# Simple character mapping
sed 'y/abc/xyz/' file.txt  # a->x, b->y, c->z

# ROT13 encoding (example)
sed 'y/abcdefghijklmnopqrstuvwxyz/nopqrstuvwxyzabcdefghijklm/' file.txt

# Map symbols
sed 'y/_-/ /' file.txt  # underscore and dash to space
```

_exec_
```bash
echo "hello WORLD" | sed 'y/hello/HELLO/'
```

_output_
```bash
HELLO woRLD
```

The y command maps each character in source-chars to matching position in dest-chars.

- Source and destination must be same length
- Maps character by position, not by pattern
- Global by nature (all occurrences)
- Cannot use regex or special patterns

#### Practical transliteration uses

```bash
# Normalize whitespace characters
sed 'y/\t/ /' file.txt  # tabs to spaces

# Date format conversion
sed 'y/-/ /' file.txt  # dashes to spaces

# Simple encoding
sed 'y/!@#$%/12345/' file.txt

# Phone number normalization
echo "123-456-7890" | sed 'y/()-/ /'

# Keyboard mapping simulation
echo "hello" | sed 'y/helo/hdlo/'  # swap e and l
```

_exec_
```bash
echo "a-b-c" | sed 'y/-/ /'
```

_output_
```bash
a b c
```

y command translates each character in source to corresponding destination.

- All matching characters are replaced
- Order matters; source[n] -> dest[n]
- Source and dest lengths must match exactly

**Best practices:**

- Use single quotes to avoid shell interpretation
- Verify source/dest lengths are equal
- Test on sample data before production

**Common errors:**

- **Strings not same length**: Ensure source and dest have equal characters

### Hold Space Operations

Use hold space for advanced transformations

**Keywords:** hold space, pattern space, h g x, advanced

#### Pattern and hold space basics

```bash
# Sed maintains two buffers:
# Pattern space = current line being processed
# Hold space = auxiliary buffer for storage

# h = copy pattern space to hold space
# g = copy hold space to pattern space
# x = exchange pattern and hold spaces
# H = append pattern space to hold space
# G = append hold space to pattern space

# Swap adjacent lines
sed 'N;h;s/\n/ /;x;s/ /\n/;U' file.txt

# Reverse entire file
sed '1h;1!H;$!d;x' file.txt
```

_exec_
```bash
echo -e "A\nB\nC" | sed '1h;1!H;$!d;x'
```

_output_
```bash
C
B
A
```

Complex hold space operations can reverse line order and enable advanced transformations.

- Hold space starts empty
- Advanced feature; complex to master
- Enables multi-line transformations
- Powerful for sophisticated operations

#### Practical hold space examples

```bash
# Print lines in reverse order
sed -n '1h;1!H;$!d;x;p' file.txt

# Print every other line
sed -n 'N;P' file.txt

# Duplicate each line
sed 'h;p' file.txt

# Process pairs of lines
sed 'N;s/\n/ /' file.txt  # merge pairs
```

_exec_
```bash
echo -e "1\n2\n3\n4" | sed 'N;s/\n/-/'
```

_output_
```bash
1-2
3-4
```

N appends next line to pattern space; useful for multi-line operations.

- N = read next line into pattern space
- Creates multi-line patterns
- Enables cross-line substitutions

**Best practices:**

- Use for advanced multi-line operations
- Test carefully; logic can be complex
- Document what each command does

**Common errors:**

- **Logic not working as expected**: Test each part separately; track space contents mentally

### Print Commands

Various line printing and display options

**Keywords:** print, p command, l command, display, output

#### Print commands

```bash
# p = print current pattern space
# l = list line (shows non-printing chars)
# = = print line number
# Combine with -n for selective printing

# Print specific lines
sed -n '5p' file.txt

# Print pattern-matching lines
sed -n '/error/p' file.txt

# Print with line numbers
sed -n '=/error/p' file.txt  # prints line number then line

# Print non-printing characters visible
sed -n 'l' file.txt  # shows tabs, spaces, newlines
```

_exec_
```bash
echo -e "hello\tworld\ntest" | sed -n 'l'
```

_output_
```bash
hello\tworld$
test$
```

The l command shows whitespace and line endings explicitly.

- p prints line (use with -n to avoid duplication)
- l shows visible representation (tabs, spaces, newlines)
- = prints current line number
- Useful for debugging and visualization

#### Selective output with options

```bash
# Duplicate matching lines
sed '/pattern/p' file.txt

# Print line numbers for matches
sed -n '/error/=' file.txt

# Print line number and content
sed -n '/pattern/={=;p;}' file.txt

# Show matching context
sed -n '/start/,/end/p' file.txt

# Count and show matches
sed -n '/pattern/p' file.txt | wc -l
```

_exec_
```bash
echo -e "match\nnomatch\nmatch" | sed -n '/match/p'
```

_output_
```bash
match
match
```

-n with p prints only matching lines; useful instead of grep for modifications.

- p without -n duplicates lines
- -n alone suppresses all output
- p flag in s command (s///p) prints substitutions

**Best practices:**

- Use -n p for grep-like filtering with modifications
- Use l for debugging whitespace issues
- Document output format in scripts

**Common errors:**

- **Lines printed twice**: Use -n with p to suppress default printing

## Advanced Operations

Branches, labels, and complex operations

### Branches and Labels

Control flow with branches and labels

**Keywords:** branch, label, b command, t command, control flow

#### Branch and label commands

```bash
# b [label] = branch to label or end
# t [label] = branch if substitution made
# T [label] = branch if no substitution (GNU sed)
# : label = define label name

# Basic branch
sed ':start; s/aa/a/; t start' file.txt

# Repeat substitution until no match
sed ':a; s/  / /g; t a' file.txt

# Conditional branch
sed '/pattern/{=; b end}; d; :end' file.txt

# Skip section
sed '/skip/b skip; s/a/b/g; :skip' file.txt
```

_exec_
```bash
echo "aaa" | sed ':a; s/aa/a/; ta'
```

_output_
```bash
a
```

The t command branches to label if substitution succeeded; loop removes double 'a's.

- b branches unconditionally
- t branches only if substitution made
- Labels defined with: notation
- Creates loops for repeated operations

#### Practical branch patterns

```bash
# Multiple substitutions in sequence
sed 's/foo/bar/; s/old/new/; s/a/b/' file.txt

# Skip certain lines
sed '/^#/{N; b}; s/^/  /' file.txt

# Process based on condition
sed '/match/{s/a/b/; b skip}; s/x/y/; :skip' file.txt

# Complex multi-pattern logic
sed '/start/,:end {s/x/y/; /end/b; n; b;} d' file.txt
```

_exec_
```bash
echo -e "foo\nbar\nbaz" | sed 's/foo/FOO/; t skip; s/./X/; :skip'
```

_output_
```bash
FOO
XXX
XXX
```

t skips further processing if substitution succeeds, implementing conditional logic.

- Enables complex multi-step logic
- Useful for avoiding redundant operations
- More efficient than multiple passes

**Best practices:**

- Use branches carefully; test extensively
- Document branch logic in comments
- Keep branch depth shallow for readability

**Common errors:**

- **Infinite loop**: Ensure branch conditions eventually fail

### Multiple Scripts

Combining multiple sed commands and scripts

**Keywords:** multiple commands, -e flag, -f flag, script files

#### Multiple -e scripts

```bash
# Multiple -e flags for separate commands
sed -e 's/a/b/' -e 's/c/d/' file.txt

# Equivalent to semicolon separation
sed 's/a/b/; s/c/d/' file.txt

# Multiple -e with complex operations
sed -e '/pattern/d' -e 's/x/y/' file.txt

# Each -e is processed in order
sed -e '1s/^/HEAD: /' -e '$a\TAIL'  file.txt
```

_exec_
```bash
echo -e "a\nb\nc" | sed -e 's/a/A/' -e 's/b/B/'
```

_output_
```bash
A
B
c
```

Multiple -e flags apply each script sequentially to each line.

- -e and ; are equivalent for multiple commands
- Order matters; first command output feeds to next
- Each line processed through all commands

#### Script files with -f

```bash
# Save script to file, use with -f
# File: myscript.sed
# Contents:
# s/old/new/g
# /pattern/d
# /^#/d

# Execute script file
sed -f myscript.sed file.txt

# Multiple script files
sed -f script1.sed -f script2.sed file.txt

# Create and run script
cat > /tmp/script.sed << 'EOF'
s/foo/bar/g
s/hello/hi/
/^$/d
EOF
sed -f /tmp/script.sed file.txt
```

_exec_
```bash
cat > /tmp/test.sed << 'EOF'
s/x/X/g
/^$/d
EOF
echo -e "x\n\nY" | sed -f /tmp/test.sed
```

_output_
```bash
X
Y
```

Script files organize complex sed operations for reusability.

- -f allows script in file
- Easier to manage complex scripts
- Can version control scripts
- Comments with # in script files

**Best practices:**

- Use -f for complex or reusable scripts
- Keep scripts well-commented
- Test scripts before production use

**Common errors:**

- **No such file or directory**: Verify script file path and permissions

### Regular Expressions

Advanced regex patterns and options

**Keywords:** regex, regular expressions, -E flag, extended regex, patterns

#### Basic vs extended regex

```bash
# Basic regex: sed 's/pattern/replacement/'
# Extended regex: sed -E 's/pattern/replacement/'

# Basic: escape special chars
sed 's/\(.*\)/[\1]/' file.txt

# Extended: no escaping needed
sed -E 's/(.*)/[\1]/' file.txt

# Extended groups
sed -E 's/([0-9]+)-([0-9]+)/\2-\1/' file.txt

# Use -E for clarity and consistency
sed -E 's/(foo|bar)/FOUND/' file.txt
```

_exec_
```bash
echo "123-456" | sed -E 's/([0-9]+)-([0-9]+)/\2-\1/'
```

_output_
```bash
456-123
```

Extended regex (-E) provides modern regex syntax with fewer escapes.

- -E (GNU) or -r (BSD) enables extended regex
- Less escaping in extended mode
- More readable patterns
- Recommended for consistency

#### Advanced pattern matching

```bash
# Capture groups and backreferences
sed -E 's/([a-z]+) ([a-z]+)/\2 \1/' file.txt

# Lookahead-like patterns
sed -E 's/([0-9]+)([a-z])/\1 \2/' file.txt

# Complex patterns
sed -E 's/^([^:]*):(.*)$/\2:\1/' file.txt

# Word boundaries (in extended mode)
sed -E 's/\bword\b/WORD/' file.txt

# Multiple alternatives
sed -E 's/(foo|bar|baz)/MATCH/' file.txt
```

_exec_
```bash
echo "John Smith" | sed -E 's/([A-Za-z]+) ([A-Za-z]+)/\2, \1/'
```

_output_
```bash
Smith, John
```

Regex groups and backreferences enable sophisticated text rearrangement.

- \1, \2... reference captured groups
- Groups defined by ( ) in extended mode
- Powerful for text reformatting

**Best practices:**

- Use -E for modern regex syntax
- Test regex patterns independently first
- Document complex patterns with comments

**Common errors:**

- **Backreference not working**: Verify escaping and group count matches

## In-Place Editing

Modify files directly with sed

### File Modification

Edit files in place with -i flag

**Keywords:** in-place, -i flag, modify files, file editing

#### In-place file editing

```bash
# -i flag: edit files in-place
# Changes written back to original file

# Simple in-place substitution
sed -i 's/old/new/' file.txt

# In-place with extended regex
sed -i -E 's/(pattern)/replacement/' file.txt

# In-place on multiple files
sed -i 's/find/replace/' *.txt

# Apply to specific line
sed -i '5s/text/TEXT/' file.txt

# Note: -i modifies original file directly
sed -i 's/a/b/' important.txt  # NO BACKUP!
```

_exec_
```bash
echo -e "test\ntext" > /tmp/test.txt
sed -i 's/test/TEST/' /tmp/test.txt
cat /tmp/test.txt
```

_output_
```bash
TEST
text
```

The -i flag modifies files in place; changes are written to original file.

- Dangerous without backup; file is modified immediately
- No recovery possible if mistake made
- Use backup option (-i.bak) when testing

#### Backup before modification

```bash
# Create backup with -i flag
# -i.bak creates backup with .bak extension

# Backup example
sed -i.bak 's/old/new/' file.txt
# Creates: file.txt (modified) and file.txt.bak (original)

# Custom backup extension
sed -i.orig 's/pattern/replacement/' file.txt
# Creates: file.txt (modified) and file.txt.orig (original)

# Backup with timestamp
sed -i.$(date +%s).bak 's/a/b/' file.txt

# Backup multiple files
sed -i.bak 's/find/replace/' *.conf
```

_exec_
```bash
echo "original" > /tmp/backup_test.txt
sed -i.backup 's/original/modified/' /tmp/backup_test.txt
echo "Modified:" && cat /tmp/backup_test.txt
echo "Backup:" && cat /tmp/backup_test.txt.backup
```

_output_
```bash
Modified:
modified
Backup:
original
```

Backup extension creates copy of original before modification for safety.

- Always use backup for important files
- Backup contains original unmodified content
- Can verify changes by comparing files

**Best practices:**

- Always use backup (-i.bak) for production files
- Test modifications on sample file first
- Verify changes before deleting backups

**Common errors:**

- **File corrupted after sed -i**: Use -i.bak to maintain backup next time

### Platform Differences

GNU sed vs BSD sed variations

**Keywords:** GNU sed, BSD sed, macOS, platform differences

#### GNU vs BSD sed differences

```bash
# GNU sed (Linux) vs BSD sed (macOS default)
# Key differences:

# 1. In-place editing syntax:
# GNU: sed -i 's/a/b/' file.txt (no space)
# BSD: sed -i '' 's/a/b/' file.txt or sed -i.bak 's/a/b/' file.txt

# 2. Extended regex flags:
# GNU: sed -r 's/(a)/[\1]/' file.txt
# BSD: sed -E 's/(a)/[\1]/' file.txt

# 3. GNU-only features:
# BSD doesn't support: 0~step, e flag, T command

# 4. Escape sequences in replacement:
# GNU: \L (lowercase), \U (uppercase)
# BSD: Not supported; use tr instead
```

_exec_
```bash
sed --version 2>&1 | head -1 || echo "BSD sed (or compatible)"
```

_output_
```bash
GNU sed, version 4.9
```

Checking sed version helps determine feature availability.

- GNU sed is more feature-rich
- BSD sed is simpler but less capable
- macOS ships with BSD sed by default
- Install GNU sed via Homebrew on macOS

#### Writing portable sed scripts

```bash
# Portable sed patterns (work on both GNU/BSD):

# Use -e for clarity (both support it)
sed -e 's/old/new/' -e 's/foo/bar/' file.txt

# Use -E instead of -r (more portable)
sed -E 's/(pattern)/[\1]/' file.txt

# Avoid GNU-only features:
# Don't use: 0~step, T, L, U escape sequences, e flag

# For macOS/BSD, install GNU sed:
# brew install gnu-sed
# Use as: gsed command file.txt

# Portable in-place editing:
sed -i.bak 's/pattern/replacement/' file.txt
rm file.txt.bak  # cleanup
```

_exec_
```bash
echo "TEST" | sed -E 's/([A-Z]+)/[\1]/g'
```

_output_
```bash
[T][E][S][T]
```

Using -E and avoiding GNU-specific features ensures portable scripts.

- -E works on both GNU and BSD
- -r is GNU-only (not portable)
- Think about target systems before scripting

**Best practices:**

- Test scripts on both platforms if possible
- Use portable syntax (avoid GNU extensions)
- Specify shebang `#!/bin/sed -f` for scripts

**Common errors:**

- **Script fails on macOS**: Check for GNU-specific features; test -E works

## Practical Examples

Real-world sed usage scenarios

### Real-World Use Cases

Practical application examples

**Keywords:** practical, examples, real-world, use cases

#### Log file processing

```bash
# Extract error lines from logs
sed -n '/ERROR/p' app.log

# Remove timestamp prefix
sed 's/^\[[^]]*\] //' app.log

# Filter and format errors
sed -n '/ERROR/{s/ERROR/[!]/p;}' app.log

# Gzip compress, preserving original processing
sed 's/\.log$/.log.gz/' <<<log_list.txt | xargs gzip

# Remove ANSI color codes
sed 's/\x1b\[[0-9;]*m//g' colored.log
```

_exec_
```bash
echo -e "[2025-01-01 10:00:00] Starting\n[2025-01-01 10:00:01] ERROR: Failed\n[2025-01-01 10:00:02] Done" | sed -n '/ERROR/p'
```

_output_
```bash
[2025-01-01 10:00:01] ERROR: Failed
```

Sed efficiently filters and processes log files for analysis.

- Fast for large log processing
- Combine with pipes for complex workflows
- Better than loading entire file in memory

#### Configuration file editing

```bash
# Enable/disable settings
sed -i 's/^#\(enable_feature\)/\1/' config.conf

# Change parameter values
sed -i 's/^\(parameter\)=.*/\1=newvalue/' config.conf

# Add configuration if missing
sed -i '/^\[section\]/a\new_option=value' config.ini

# Update port in config
sed -i 's/port=[0-9]*/port=8080/' app.conf

# Comment out deprecated options
sed -i 's/^\(deprecated_option\)/#\1/' config.conf
```

_exec_
```bash
echo "enable_feature=false" > /tmp/config.conf
sed -i 's/enable_feature=.*/enable_feature=true/' /tmp/config.conf
cat /tmp/config.conf
```

_output_
```bash
enable_feature=true
```

Sed automates configuration file updates without manual editing.

- Safer than manual editing
- Scriptable for automation
- Essential for infrastructure as code

#### Data format conversion

```bash
# CSV to space-separated
sed 's/,/ /g' data.csv

# URL decode (simple version)
sed 's/%20/ /g; s/%2F/\//g' encoded.txt

# Convert tabs to spaces
sed 's/\t/  /g' data.tsv

# Format SQL queries
sed 's/ where / WHERE /i; s/ and / AND /i' query.sql

# Convert JSON keys to uppercase
sed 's/"[^"]*":/\U&/g' data.json
```

_exec_
```bash
echo "a,b,c" | sed 's/,/ /g'
```

_output_
```bash
a b c
```

Sed converts between data formats efficiently.

- Quick format transformations
- Better for simple conversions than scripting

#### Code refactoring

```bash
# Rename function/variable
sed -i 's/\boldName\b/newName/g' *.js

# Add copyright header to files
sed -i '1i/* Copyright 2025 */' *.js

# Convert var to const
sed -i 's/^var /const /g' script.js

# Update import paths
sed -i "s|from './old|from './new|g" *.ts

# Remove console.log statements (careful!)
sed -i '/console\.log/d' app.js
```

_exec_
```bash
echo "var x = 5;" | sed 's/^var /const /'
```

_output_
```bash
const x = 5;
```

Sed automates code refactoring across multiple files.

- Use -i.bak for safety
- Test patterns first
- Great for large codebase refactoring

#### Text formatting

```bash
# Add line numbers
sed = file.txt | sed 'N;s/\n/: /'

# Add indentation
sed 's/^/  /' file.txt

# Remove empty lines
sed '/^$/d' file.txt

# Wrap long lines
sed 's/\(.\{1,80\}\) /\1\n/g' file.txt

# Capitalize first letter
sed 's/^./\U&/' file.txt
```

_exec_
```bash
echo -e "first\nsecond\nthird" | sed = | sed 'N;s/\n/. /'
```

_output_
```bash
1. first
2. second
3. third
```

Sed formats text output efficiently.

- Useful for report generation
- Combines well with other tools

#### File cleanup and normalization

```bash
# Remove trailing whitespace
sed 's/[[:space:]]*$//' file.txt

# Remove duplicate blank lines
sed '/^$/N;/^\n$/!P;D' file.txt

# Normalize line endings (CRLF to LF)
sed 's/\r$//' windows.txt

# Remove control characters
sed 's/\x00//g' file.txt

# Convert DOS to Unix
sed 's/\r$//' dos_file.txt > unix_file.txt
```

_exec_
```bash
echo -e "line1  \nline2 \t" | sed 's/[[:space:]]*$//'
```

_output_
```bash
line1
line2
```

Sed cleans whitespace and normalizes file encoding.

- Essential for data preprocessing
- Improves data quality

**Best practices:**

- Test on sample data before production
- Use backup (-i.bak) for file modifications
- Document complex sed commands in comments
- Combine sed with other tools for powerful pipelines

**Common errors:**

- **Unintended modifications**: Test patterns thoroughly; use backups

### Performance Tips

Optimization and performance best practices

**Keywords:** performance, optimization, efficiency, speed, large files

#### Performance considerations

```bash
# Use sed for line-by-line processing
# Better than loading entire file in memory

# Avoid unnecessary commands
# This is slow: multiple passes
sed 's/a/b/' file | sed 's/c/d/' | sed 's/e/f/'

# This is faster: combine operations
sed 's/a/b/; s/c/d/; s/e/f/' file

# Limit address ranges
# Slow: search entire file
sed 's/pattern/replacement/' huge.txt

# Faster: limit to relevant lines
sed '100,200s/pattern/replacement/' file.txt

# Use -n with p for filtering
# Better than piping to grep
sed -n '/pattern/p' file | wc -l  # Slow
sed -n '/pattern/p' file | wc -l  # Still works
```

_exec_
```bash
time seq 1 1000 | sed 's/1/2/'
```

_output_
```bash
real	0m0.005s
user	0m0.003s
sys	0m0.001s
```

Sed processes efficiently even with large inputs.

- Stream processing avoids memory overhead
- Single pass generally fastest
- Combining operations reduces overhead

#### Optimization techniques

```bash
# Use specific addresses to reduce work
# Instead of: sed 's/a/b/g' (every line)
sed '1,100s/a/b/g' file.txt  # only first 100 lines

# Use simpler regex patterns
# Complex: sed 's/^[[:space:]]*([a-zA-Z_][a-zA-Z0-9_]*).*$/\1/'
# Simpler: sed 's/^[^:]*:'  # if suitable

# Avoid expensive regex operations
# Slow: sed 's/.*\(pattern\).*/\1/'
# Better: sed -n 's/.*\(pattern\).*/\1/p'

# Use -i for in-place without temp files
# Avoids: cp file file.bak; sed ... file.bak > file; rm file.bak

# Avoid recursive holds/branching
# Test termination conditions carefully
```

_exec_
```bash
# Demonstrate efficient skipping
seq 1 5 | sed '/3/d'  # Skip specific lines
```

_output_
```bash
1
2
4
5
```

Efficient filtering removes unnecessary processing of lines.

- Plan logic carefully to minimize work
- Profile with time command for large files
- Consider awk/perl for very complex operations

#### Large file handling

```bash
# Processing large files efficiently

# Split large file, process in parallel
split -n l/4 large.txt tmp_

# Process each chunk
for chunk in tmp_*; do
  sed 's/pattern/replacement/' "$chunk" > "$chunk.out"
done

# Merge results
cat tmp_*.out > output.txt

# Use sed with tail for end-of-file operations
tail -100 large.txt | sed 's/a/b/'

# Stream processing (best for large files)
sed 's/old/new/' input.txt > output.txt  # Better than loading all in memory
```

_exec_
```bash
# Create sample data
seq 1 10 > /tmp/large.txt
# Process with sed
sed 's/1/ONE/g' /tmp/large.txt | head -5
```

_output_
```bash
ONE
2
3
4
5
```

Sed processes large files efficiently through streaming.

- Stream processing avoids memory issues
- Process in chunks for parallelization
- Pipe directly without temp files when possible

**Best practices:**

- Profile code with time command
- Test on representative data
- Use simplest regex that works
- Combine operations to reduce passes

**Common errors:**

- **Out of memory on large file**: Use streaming; avoid loading entire file
