---
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 sed reference covers basic text substitution through advanced scripting techniques, with practical examples for text processing, file editing, and automation.

## Getting Started

Introduction to sed and basic concepts

### What is Sed

What sed does 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 handles simple text transformations with 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**: Match and escape the delimiters correctly

### 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 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**: Use matching delimiters on both sides

### 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 to replace every match, not just the first
- Consider case-insensitivity with i flag
- Test the pattern first to confirm what it 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
- Filters lines 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
- Suits sampling or striping every nth line
- 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 to narrow the set of lines targeted

**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**: Source and destination must have the same number of 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
```

Hold space operations can reverse line order and carry data between lines.

- Hold space starts empty
- Advanced feature; complex to master
- Enables multi-line transformations
- Needed for reversing, pairing, and sorting lines

#### 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**: Make 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 rearrange parts of a line.

- \1, \2... reference captured groups
- Groups defined by ( ) in extended mode
- Used 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 keeps scripts portable.

- -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 filters and reformats 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
- Useful 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.

- 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
- Works across a whole codebase in one command

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

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

- Useful for data preprocessing
- Prevents parse errors from stray characters

**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 in 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 handles large inputs without loading the whole file into memory.

- 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
```

Deleting lines early keeps later commands from processing them.

- 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 streams large files line by line.

- 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
