Skip to content
Mikhail Deynekin edited this page Dec 22, 2025 · 1 revision

📖 sr Wiki Documentation

The Complete User Guide for Search & Replace Tool


📚 Table of Contents

🚀 Getting Started

  1. Home
  2. Installation Guide
  3. Quick Start Tutorial
  4. Basic Examples

⚙️ Core Concepts

  1. Architecture Overview
  2. Session System
  3. Backup & Rollback
  4. Binary File Detection

🔧 Usage Guides

  1. Command Reference
  2. Pattern Matching Guide
  3. Regular Expressions
  4. Environment Variables

🛠️ Advanced Topics

  1. Tool Configuration
  2. Performance Tuning
  3. Security Hardening
  4. Enterprise Deployment

📊 Reference

  1. FAQ
  2. Troubleshooting
  3. Error Codes
  4. Compatibility Matrix

🤝 Community

  1. Contributing Guide
  2. Code of Conduct
  3. Support Channels

🏠 Home

Welcome to the official documentation for sr (Search & Replace) – the enterprise-grade text replacement utility designed for safety, reliability, and professional workflow integration.

What is sr?

sr is a sophisticated command-line tool that provides safe, predictable, and auditable text replacements across multiple files. Unlike basic tools like sed -i, sr implements a comprehensive safety-first approach with industrial-strength features:

  • Multi-layer binary detection to prevent accidental corruption
  • Session-based backup management with complete audit trails
  • One-command rollback capabilities
  • Ownership and permission preservation
  • Configurable safety limits and exclusions

Key Features at a Glance

Feature Benefit Example
Session Tracking Complete audit trail of every operation sr --rollback-list
Multi-layer Safety Protection against accidental data loss Automatic backups, binary detection
Tool Configuration Direct parameter passing to core utilities --find-opts, --sed-opts, --grep-opts
Extended Search Advanced pattern matching capabilities -i, -E, -w flags
Cross-Platform Works on Linux, macOS, BSD systems Consistent behavior across environments

Quick Navigation

Philosophy

sr is built on three core principles:

  1. Safety First: No operation should risk data loss
  2. Predictability: Behavior should be consistent and unambiguous
  3. Auditability: Every change should be traceable and reversible

Version Information

  • Current Stable: v6.1.0
  • Minimum Requirements: Bash 5.0+, find, sed, grep
  • License: MIT
  • Maintainer: Mikhail Deynekin

Getting Help

Quick Example

# Install and test
curl -L https://raw.githubusercontent.com/paulmann/sr-search-replace/main/sr.sh -o sr
chmod +x sr
./sr --version

# Basic usage
./sr "*.html" "old-domain.com" "new-domain.com"

# Safe testing
./sr --dry-run -v "*.js" "var " "const "

📥 Installation Guide

Complete installation instructions for all supported platforms and environments.

Prerequisites

sr requires a POSIX-compliant shell environment with standard utilities:

Required Core Utilities

Tool Minimum Version Purpose How to Check
bash 5.0 Shell interpreter bash --version
find 4.0 File discovery find --version
sed 4.0 Stream editor sed --version
grep 3.0 Pattern matching grep --version

Recommended Utilities

Tool Purpose Benefit
file MIME type detection Enhanced binary file detection
stat File metadata Ownership/permission preservation
realpath Path resolution Better path handling
bc Mathematical calculations Performance metrics

Installation Methods

Method 1: Direct Download (Recommended for most users)

# Download the latest version
curl -L https://raw.githubusercontent.com/paulmann/sr-search-replace/main/sr.sh -o sr

# Make it executable
chmod +x sr

# Test the installation
./sr --version

# Install globally (optional)
sudo cp sr /usr/local/bin/

Method 2: Git Clone (For development or customization)

# Clone the repository
git clone https://github.com/paulmann/sr-search-replace.git
cd sr-search-replace

# Make the script executable
chmod +x sr.sh

# Create a symbolic link
sudo ln -s "$(pwd)/sr.sh" /usr/local/bin/sr

# Verify installation
sr --help | head -5

Method 3: Package Manager (For system administrators)

Debian/Ubuntu:

# Create a DEB package structure
mkdir -p sr-package/usr/local/bin
cp sr.sh sr-package/usr/local/bin/sr
chmod 755 sr-package/usr/local/bin/sr

# Build the package
dpkg-deb --build sr-package sr_6.1.0_all.deb

# Install
sudo dpkg -i sr_6.1.0_all.deb

RHEL/CentOS:

# Create RPM spec file (simplified example)
cat > sr.spec << 'EOF'
Name: sr
Version: 6.1.0
Release: 1%{?dist}
Summary: Search and Replace Tool
License: MIT

%install
mkdir -p %{buildroot}/usr/local/bin
install -m 755 sr.sh %{buildroot}/usr/local/bin/sr

%files
/usr/local/bin/sr
EOF

# Build and install
rpmbuild -ba sr.spec
sudo rpm -ivh ~/rpmbuild/RPMS/x86_64/sr-6.1.0-1.el7.x86_64.rpm

Platform-Specific Instructions

Linux Distributions

Ubuntu/Debian:

sudo apt-get update
sudo apt-get install bash findutils sed grep file coreutils

RHEL/CentOS/Fedora:

sudo yum install bash findutils sed grep file coreutils
# or for newer versions
sudo dnf install bash findutils sed grep file coreutils

Arch Linux:

sudo pacman -S bash findutils sed grep file coreutils

macOS

Using Homebrew (Recommended):

# Install GNU versions for best compatibility
brew install bash findutils gnu-sed grep file coreutils

# Link GNU sed (important!)
brew link --force gnu-sed

# Add to PATH if needed
echo 'export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"' >> ~/.bash_profile

Using MacPorts:

sudo port install bash findutils gsed grep file coreutils

BSD Systems

FreeBSD:

pkg install bash findutils gsed grep file coreutils

OpenBSD:

pkg_add bash findutils gsed grep file coreutils

Docker Installation

Official Docker Image:

# Pull the image
docker pull ghcr.io/paulmann/sr:latest

# Run interactively
docker run -it --rm -v "$(pwd):/work" ghcr.io/paulmann/sr:latest \
  sr "*.txt" "search" "replace"

# Or build your own
cat > Dockerfile << 'EOF'
FROM alpine:3.14
RUN apk add --no-cache bash findutils sed grep file coreutils
COPY sr.sh /usr/local/bin/sr
RUN chmod +x /usr/local/bin/sr
ENTRYPOINT ["/usr/local/bin/sr"]
EOF

Verification & Testing

After installation, verify everything works correctly:

# Test 1: Check version
sr --version

# Test 2: Check dependencies
for cmd in bash find sed grep; do
    if command -v $cmd >/dev/null 2>&1; then
        echo "$cmd: $(which $cmd)"
    else
        echo "$cmd: NOT FOUND"
    fi
done

# Test 3: Basic functionality test
cat > test-file.txt << 'EOF'
Hello World
This is a test
EOF

sr --dry-run "test-file.txt" "test" "TEST"
rm test-file.txt

Upgrade Instructions

From v6.0.0 to v6.1.0:

# Backup any custom configurations
cp ~/.sr_config ~/.sr_config.backup 2>/dev/null || true

# Download new version
curl -L https://raw.githubusercontent.com/paulmann/sr-search-replace/main/sr.sh -o /tmp/sr_new
chmod +x /tmp/sr_new

# Test new version
/tmp/sr_new --version
/tmp/sr_new --dry-run "*.txt" "test" "TEST"

# Replace if tests pass
sudo cp /tmp/sr_new /usr/local/bin/sr
rm /tmp/sr_new

From older versions:

# Full reinstallation recommended
sudo rm /usr/local/bin/sr 2>/dev/null || true
curl -L https://raw.githubusercontent.com/paulmann/sr-search-replace/main/sr.sh -o sr
chmod +x sr
sudo cp sr /usr/local/bin/

Uninstallation

# Remove the binary
sudo rm /usr/local/bin/sr 2>/dev/null || true

# Remove backup directories (if desired)
find . -type d -name "sr.backup.*" -exec rm -rf {} + 2>/dev/null || true

# Remove configuration files
rm ~/.sr_config 2>/dev/null || true

Common Installation Issues

Issue: "Command not found" after installation

Solution: Ensure /usr/local/bin is in your PATH:

echo $PATH | grep -q "/usr/local/bin" || echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Issue: "Permission denied" when running

Solution: Ensure execute permissions:

chmod +x /usr/local/bin/sr

Issue: Older sed version on macOS

Solution: Install GNU sed:

brew install gnu-sed
brew link --force gnu-sed

Issue: Missing file utility

Solution: Install the file package:

# Ubuntu/Debian
sudo apt-get install file

# RHEL/CentOS
sudo yum install file

# macOS
brew install file

Next Steps

After successful installation, proceed to:


🏃 Quick Start Tutorial

Get started with sr in 10 minutes. This tutorial covers essential operations and safety practices.

Before You Begin

Ensure sr is installed and accessible:

sr --version
# Should output: sr - Search and Replace Tool, Version 6.1.0

Lesson 1: Your First Replacement

Let's start with a simple text replacement:

# Create a test file
echo "Hello Old World" > test.txt
echo "Another old example" >> test.txt

# Perform replacement (case-sensitive by default)
sr "test.txt" "old" "new"

# Check the result
cat test.txt
# Output:
# Hello Old World  (Note: 'Old' not replaced - case sensitive)
# Another new example

Key Takeaway: By default, sr is case-sensitive. The word "Old" wasn't replaced because it starts with capital O.

Lesson 2: Safe Testing with Dry-Run

Always test before making changes:

# Create test files
echo "config_value = production" > config1.txt
echo "config_value = production" > config2.txt

# Test what would change
sr --dry-run "*.txt" "production" "staging"
# Output shows what would be changed without actually modifying files

# Now apply the changes
sr "*.txt" "production" "staging"

# Verify
grep "staging" *.txt

Safety Rule #1: Always use --dry-run first when working with important files.

Lesson 3: Working with Multiple Files

sr excels at batch operations:

# Create multiple HTML files
cat > page1.html << 'EOF'
<html>
<title>Old Site</title>
<body>Welcome to old.example.com</body>
</html>
EOF

cat > page2.html << 'EOF'
<html>
<title>Contact Old Site</title>
<body>Email: info@old.example.com</body>
</html>
EOF

# Replace domain in all HTML files
sr "*.html" "old.example.com" "new.example.com"

# Check results
grep -n "example.com" *.html

Lesson 4: Using Case-Insensitive Search

The -i flag makes searches case-insensitive:

echo "TEST value" > demo.txt
echo "test VALUE" >> demo.txt
echo "Test Value" >> demo.txt

# Case-sensitive (default) - only matches exact case
sr --dry-run "demo.txt" "test" "demo"
# Would only match line 2

# Case-insensitive - matches all variations
sr -i --dry-run "demo.txt" "test" "demo"
# Would match all three lines

Lesson 5: Working with Word Boundaries

Prevent partial matches with word boundaries (-w flag):

echo "cat category catalog" > words.txt

# Without word boundary - replaces 'cat' everywhere
sr --dry-run "words.txt" "cat" "dog"
# Result: "dog dogegory dogalog"

# With word boundary - only replaces whole word 'cat'
sr -w --dry-run "words.txt" "cat" "dog"
# Result: "dog category catalog"

Lesson 6: Your First Rollback

sr's session system makes recovery easy:

# Make some changes
echo "Original content" > important.txt
sr "important.txt" "Original" "Modified"

# Oops! We need to undo that
sr --rollback

# Verify restoration
cat important.txt
# Output: Original content

Safety Rule #2: sr creates automatic backups. Use --rollback to recover from mistakes.

Lesson 7: Working with Directories

Process files recursively in directories:

# Create directory structure
mkdir -p project/{src,config,docs}
echo "api_key = old_key" > project/config/prod.cfg
echo "api_key = old_key" > project/config/dev.cfg
echo "// TODO: old implementation" > project/src/main.js

# Update all configuration files
sr "project/**/*.cfg" "old_key" "new_key"

# Update source files (non-recursive in each directory)
sr -nr "project/src/*.js" "TODO:" "DONE:"

Lesson 8: Excluding Files and Directories

Prevent processing of certain files:

# Create test structure
mkdir -p test/{public,private}
echo "public data" > test/public/file.txt
echo "private data" > test/private/file.txt
echo "ignore this" > test/ignore.txt

# Exclude private directory and specific files
sr -xd "private" -xp "ignore.txt" "test/**/*.txt" "data" "information"

Lesson 9: Setting Safety Limits

Protect against accidental large-scale operations:

# Limit search depth to prevent deep recursion
sr -md 2 "**/*.log" "error" "warning"

# Limit file size (skip files larger than 10MB)
sr -xs 10 "*.log" "ERROR" "WARNING"

# Combine multiple safety limits
sr -md 3 -xs 5 -xd "node_modules,vendor" "**/*.js" "var " "const "

Lesson 10: Putting It All Together

Real-world example: Refactor a codebase:

# 1. First, always test with dry-run
sr --dry-run -v -i "src/**/*.js" "oldFunctionName" "newFunctionName"

# 2. Check for any binary files that might be affected
sr --dry-run --binary-method=multi_layer "src/**/*" "oldFunctionName" "newFunctionName"

# 3. Apply changes with comprehensive backups
sr -v -i "src/**/*.js" "oldFunctionName" "newFunctionName"

# 4. Verify the changes
grep -r "newFunctionName" src/ | head -5

# 5. Check session for possible rollback
sr --rollback-list

Practice Exercises

  1. Exercise 1: Create three text files with the word "test" in different cases. Replace all variations with "experiment" using a single command.
  2. Exercise 2: Create a directory with subdirectories. Replace "foo" with "bar" in all .txt files but exclude files containing "skip" in their name.
  3. Exercise 3: Make a change, then use rollback to revert it. Verify the original content is restored.
  4. Exercise 4: Use dry-run to see what would happen if you replaced "localhost" with "production-server" in all configuration files.

Quick Reference Card

# Essential commands for beginners
sr --dry-run PATTERN SEARCH REPLACE     # Test first
sr -v PATTERN SEARCH REPLACE           # Verbose mode
sr -i PATTERN SEARCH REPLACE           # Case-insensitive
sr --rollback                          # Undo last change
sr --rollback-list                     # View backup history
sr -nr PATTERN SEARCH REPLACE          # Non-recursive
sr -md 3 PATTERN SEARCH REPLACE        # Limit depth to 3

Next Steps

Congratulations! You've completed the quick start tutorial. Continue with:


📝 Basic Examples

Practical examples demonstrating common use cases for sr. Each example includes the command, expected outcome, and important notes.

File Management Examples

Example 1: Renaming Variables in Source Code

# Scenario: Migrate from var to const/let in JavaScript
sr -i "src/**/*.js" "var " "let "
# Note: The space after 'var' prevents matching 'variable', 'variance', etc.

# More precise: Only match at beginning of lines or after specific patterns
sr -E "src/**/*.js" "(^|[^a-zA-Z0-9_])var ([a-zA-Z0-9_]+)" "\1let \2"

Example 2: Updating Configuration Values

# Update database configuration
sr "config/**/*.{yml,yaml,json}" "localhost:5432" "db-cluster.prod.example.com:5432"

# Update multiple values in one pass (using sed opts)
sr --sed-opts="-e 's/localhost:3000/api.example.com/g' -e 's/debug: true/debug: false/g'" "config/*.yml"

Example 3: Changing Domain Names in Web Content

# Update HTTP to HTTPS
sr "website/**/*.{html,htm,css,js}" "http://example.com" "https://example.com"

# Update multiple domains
for domain in blog api static; do
    sr "website/**/*" "http://$domain.old-example.com" "https://$domain.new-example.com"
done

Example 4: Copyright Year Updates

# Update copyright years
current_year=$(date +%Y)
sr -E "**/*.{js,py,html,css}" "Copyright (20[0-9]{2})-202[0-3]" "Copyright \1-$current_year"
sr -E "**/*.{js,py,html,css}" "Copyright 202[0-3]" "Copyright $current_year"

Development Workflow Examples

Example 5: Code Refactoring

# Rename a function across the codebase
sr -w "src/**/*.{js,ts,py}" "calculateTotal" "computeTotal"

# Rename a class (case-sensitive, whole words only)
sr -w "src/**/*.{js,ts}" "OldClassName" "NewClassName"

# Update imports
sr "src/**/*.{js,ts}" "from 'old-package'" "from 'new-package'"
sr "src/**/*.{js,ts}" "require('old-module')" "require('new-module')"

Example 6: TODO/Comment Management

# Mark TODOs as completed
sr -E "src/**/*.{js,py,java}" "// TODO: (.*)" "// DONE: \1"

# Add username to TODOs
username=$(whoami)
sr -E "src/**/*.{js,py,java}" "// TODO:" "// TODO($username):"

# Remove debug comments
sr "src/**/*.{js,py}" "console.debug(" "// console.debug("
sr "src/**/*.{js,py}" "print(\"DEBUG:" "# print(\"DEBUG:"

Example 7: Log Level Changes

# Change verbose logging to warning in production
sr -i "src/**/*.{js,py,java}" "log.debug" "log.warn"
sr -i "src/**/*.{js,py,java}" "logger.verbose" "logger.warning"

# Standardize error messages
sr "src/**/*.{js,py}" "console.error('Error:" "logger.error('Error:"

System Administration Examples

Example 8: Server Configuration Updates

# Update hostnames across configuration
sr "/etc/**/*.{conf,cfg}" "old-server-hostname" "new-server-hostname"

# Update IP addresses
sr "/etc/**/*" "192.168.1.100" "10.0.0.100"

# Update port numbers
sr -E "/etc/**/*" "port[[:space:]]*=[[:space:]]*3000" "port = 8080"

Example 9: Log File Processing

# Anonymize IP addresses in logs
sr -E "logs/**/*.log" "([0-9]{1,3}\.){3}[0-9]{1,3}" "[IP_REDACTED]"

# Redact sensitive information
sr -E "logs/**/*.log" "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}" "[EMAIL_REDACTED]"
sr -E "logs/**/*.log" "[0-9]{3}-[0-9]{2}-[0-9]{4}" "[SSN_REDACTED]"

Example 10: Batch File Renaming (Content-Based)

# Update internal references when renaming files
# First rename the files, then update references
for file in *.old.html; do
    new_name="${file%.old.html}.new.html"
    mv "$file" "$new_name"
    sr "**/*.{html,js,css}" "$file" "$new_name"
done

Content Management Examples

Example 11: Website Content Updates

# Update phone numbers
sr "website/**/*.{html,md,txt}" "+1-800-OLD-NUMBER" "+1-800-NEW-NUMBER"

# Update addresses
sr "website/**/*.{html,md}" "123 Old Street" "456 New Avenue"

# Update business hours
sr -i "website/**/*.{html,md}" "9am to 5pm" "8am to 6pm"

Example 12: Documentation Updates

# Update version numbers in documentation
sr "docs/**/*.{md,rst}" "version 6.0.0" "version 6.1.0"

# Update broken links
sr "docs/**/*.{md,rst}" "https://old-docs.example.com" "https://new-docs.example.com"

# Update code examples
sr "docs/**/*.{md,rst}" "python2" "python3"
sr "docs/**/*.{md,rst}" "jQuery 1.x" "jQuery 3.x"

Advanced Pattern Examples

Example 13: Multi-line Pattern Replacement

# Update multi-line configuration blocks
sr -m "config/**/*.yml" "database:\\n  host:.*\\n  port:.*" "database:\\n  host: new-host\\n  port: 5432"

# Update function signatures
sr -m "src/**/*.js" "function oldName\\(.*\\)\\n\\{" "function newName(params)\\n{"

Example 14: Conditional Replacement

# Only replace in specific contexts using complex patterns
sr -E "src/**/*.js" "(const|let|var) oldVariable =" "\1 newVariable ="

# Update CSS with vendor prefix fallbacks
sr "css/**/*.css" "-webkit-old-property" "-webkit-new-property"
sr "css/**/*.css" "-moz-old-property" "-moz-new-property"
sr "css/**/*.css" "-ms-old-property" "-ms-new-property"
sr "css/**/*.css" "old-property" "new-property"

Example 15: Template Variable Replacement

# Replace template variables with actual values
variables=(
    "COMPANY_NAME:Example Corp"
    "CURRENT_YEAR:2025"
    "SUPPORT_EMAIL:support@example.com"
)

for var in "${variables[@]}"; do
    key="${var%%:*}"
    value="${var#*:}"
    sr "templates/**/*.{html,txt}" "\{\{${key}\}\}" "$value"
done

Safety-First Examples

Example 16: Always Test First

# Golden rule: Always dry-run first
sr --dry-run -v "**/*.sql" "DROP TABLE" "-- DROP TABLE (commented)"

# Review what will be changed
sr --dry-run -n "**/*.py" "import sys" "import sys, os" | head -20

# Check for binary files
sr --dry-run --binary "**/*" "password" "[REDACTED]"

Example 17: Safe Rollback Practice

# Create a named session for important changes
export SR_BACKUP_PREFIX="migration_$(date +%Y%m%d_%H%M%S)"
sr "**/*.conf" "old-value" "new-value"

# Test rollback before committing
sr --dry-run --rollback
# If satisfied, keep changes. If not, restore:
sr --rollback

Example 18: Production Safety Rules

# Production safety wrapper
safe_sr() {
    local pattern="$1"
    local search="$2"
    local replace="$3"
    
    # Always dry-run first
    sr --dry-run -v "$pattern" "$search" "$replace" || return 1
    
    # Ask for confirmation
    read -p "Apply these changes? (yes/no): " confirm
    if [[ "$confirm" == "yes" ]]; then
        # Apply with forced backups
        sr -fb -v "$pattern" "$search" "$replace"
    else
        echo "Operation cancelled"
        return 1
    fi
}

# Usage
safe_sr "*.conf" "localhost" "production-host"

One-Liner Reference

Quick reference of common one-liners:

# Text file operations
sr "*.txt" "foo" "bar"                    # Simple replacement
sr -i "*.txt" "foo" "bar"                 # Case-insensitive
sr -w "*.txt" "word" "replacement"        # Whole words only
sr -E "*.txt" "regex(pattern)" "repl"     # Extended regex

# File management
sr "**/*.js" "search" "replace"           # Recursive
sr -nr "*.js" "search" "replace"          # Current directory only
sr -md 3 "**/*.js" "search" "replace"     # Max depth 3

# Safety features
sr --dry-run "*.conf" "old" "new"         # Test without changes
sr -fb "*.sql" "DROP" "-- DROP"           # Force backup
sr --rollback                             # Undo last operation
sr --rollback-list                        # List backups

# Tool configuration
sr --find-opts="-type f -size -1M" "*.log" "ERR" "WARN"
sr --sed-opts="-e 's/foo/bar/g' -e 's/baz/qux/g'" "*.txt" "x" "y"

Common Pitfalls and Solutions

Pitfall Solution Example
Partial word matches Use -w for word boundaries sr -w "cat" "dog" won't match "catalog"
Case sensitivity issues Use -i for case-insensitive sr -i "test" "TEST" matches "Test", "TEST", "test"
Shell expansion problems Quote patterns sr "*.txt" not sr *.txt
Binary file warnings Use --binary or exclude sr --binary "*.bin" or -xp "*.bin"
Permission errors Check file permissions Use sudo or adjust permissions

Next Steps

After mastering these basic examples, explore:


🏗️ Architecture Overview

Understanding the internal architecture of sr helps you use it effectively and troubleshoot issues. This section covers the system design, components, and data flow.

System Design Philosophy

sr is built on three core architectural principles:

  1. Modularity: Each component has a single responsibility
  2. Safety: Fail-safe defaults and reversible operations
  3. Auditability: Complete traceability of all operations

High-Level Architecture

┌─────────────────────────────────────────────────────────┐
│                    Command Line Interface                │
│  • Argument parsing                                     │
│  • Option validation                                    │
│  • User interaction                                     │
└───────────────────────────┬─────────────────────────────┘
                            │
┌───────────────────────────▼─────────────────────────────┐
│                  Core Processing Engine                  │
│  • Session management                                   │
│  • File discovery                                       │
│  • Safety checks                                        │
│  • Error handling                                       │
└──────────────┬──────────────────┬───────────────────────┘
               │                  │
┌──────────────▼──────┐   ┌──────▼───────────────────────┐
│   File Processing   │   │     Backup & Rollback        │
│  • Binary detection │   │  • Session tracking          │
│  • Text replacement │   │  • Backup creation           │
│  • Encoding handling│   │  • Rollback execution        │
└──────────────┬──────┘   └──────────────┬───────────────┘
               │                          │
┌──────────────▼──────────────────────────▼───────────────┐
│                External Tool Integration                │
│  • find - File discovery                               │
│  • sed - Text replacement                              │
│  • grep - Pattern matching                             │
│  • file - Binary detection                             │
└─────────────────────────────────────────────────────────┘

Core Components

1. Command Line Interface (CLI) Layer

Responsibilities:

  • Parse and validate command-line arguments
  • Handle user input and confirmation prompts
  • Manage output formatting and logging levels

Key Functions:

# CLI Layer handles these aspects:
parse_arguments()      # Parse command line
show_usage()          # Display help
show_version()        # Show version info
confirm_action()      # User confirmation prompts

2. Core Processing Engine

Responsibilities:

  • Orchestrate the entire replacement workflow
  • Manage session lifecycle
  • Coordinate between components
  • Handle errors and rollbacks

Workflow:

graph TD
    A[Start] --> B[Parse Arguments]
    B --> C[Initialize Session]
    C --> D[Discover Files]
    D --> E{For Each File}
    E --> F[Safety Checks]
    F --> G[Create Backup]
    G --> H[Process File]
    H --> I[Track Changes]
    I --> E
    E --> J[All Files Processed]
    J --> K[Finalize Session]
    K --> L[Display Summary]
    L --> M[End]
Loading

3. File Processing Module

Responsibilities:

  • Detect binary vs text files
  • Perform text replacements
  • Handle different encodings
  • Preserve file metadata

Binary Detection Flow:

graph LR
    A[File Input] --> B{Size > 0?}
    B -->|No| C[Not Binary]
    B -->|Yes| D[Grep Heuristic]
    D -->|Non-text| E{File Utility Available?}
    D -->|Text| C
    E -->|Yes| F[MIME Type Check]
    E -->|No| G[Use Grep Result]
    F -->|text/*| C
    F -->|Other| H[Binary]
    G -->|Binary| H
    G -->|Text| C
Loading

4. Backup & Rollback System

Responsibilities:

  • Create and manage backup sessions
  • Track modified files
  • Enable one-command restoration
  • Clean up old backups

Session Structure:

sr.backup.20241222_143022_123456789/
├── .sr_session_metadata      # JSON-like session info
├── .sr_modified_files        # List of modified files
├── .sr_file_info            # Additional metadata
└── files/                   # Original file backups
    ├── path/to/file1.txt
    ├── path/to/file2.conf
    └── ...

Data Flow

Normal Operation Flow

  1. Input Processing:

    # User command
    sr -v "*.js" "old" "new"
    
    # Internal processing:
    # 1. Parse arguments
    # 2. Validate options
    # 3. Initialize session
  2. File Discovery:

    # Uses find command with configured options
    find . -name "*.js" -type f -not -path "*/sr.backup.*"
    
    # Results filtered through exclusion patterns
    # and safety checks
  3. File Processing:

    # For each file:
    # 1. Check if binary (skip or process based on flags)
    # 2. Create backup in session directory
    # 3. Perform replacement using sed
    # 4. Track modification in session
  4. Session Finalization:

    # After all files processed:
    # 1. Update session metadata
    # 2. Display summary
    # 3. Clean up old backups if configured

Rollback Operation Flow

  1. Backup Discovery:

    # Find all backup directories
    find . -maxdepth 1 -type d -name "sr.backup.*"
  2. Session Selection:

    # User selects backup or uses latest
    # System loads session metadata
  3. Restoration:

    # For each file in backup:
    # 1. Verify backup file exists
    # 2. Restore with original permissions
    # 3. Log restoration status

Configuration Management

sr uses a three-tier configuration system:

  1. Script Defaults (lowest priority):

    # Defined in script header
    readonly DEFAULT_MAX_DEPTH=100
    readonly DEFAULT_DEBUG_MODE=false
  2. Environment Variables (medium priority):

    # User can override defaults
    export SR_MAX_DEPTH=50
    export SR_DEBUG=true
  3. Command Line Arguments (highest priority):

    # Direct override
    sr -md 10 --debug "*.txt" "old" "new"

Session Management

Sessions provide atomic, reversible operations:

# Session creation process:
# 1. Generate unique session ID
SESSION_ID="20241222_143022_123456789"

# 2. Create backup directory
BACKUP_DIR="sr.backup.${SESSION_ID}"

# 3. Store metadata
cat > "${BACKUP_DIR}/.sr_session_metadata" << EOF
SESSION_ID="$SESSION_ID"
SESSION_COMMAND="$0 $*"
SESSION_START_TIME="$(date)"
# ... more metadata
EOF

# 4. Track modified files
echo "modified/file.txt" >> "${BACKUP_DIR}/.sr_modified_files"

Error Handling Architecture

sr implements a comprehensive error handling system:

# Error hierarchy:
# Level 1: User errors (invalid arguments, permissions)
# Level 2: System errors (disk full, missing tools)
# Level 3: Processing errors (individual file failures)

# Error handling flow:
process_file() {
    if [[ ! -f "$file" ]]; then
        log_error "File not found: $file"
        return 2  # File-specific error
    fi
    
    if ! create_backup "$file"; then
        log_error "Backup failed: $file"
        return 4  # Backup error
    fi
    
    # ... processing continues
}

# Global error handling
trap 'handle_interrupt' INT TERM
trap 'log_error "Error at line $LINENO"' ERR

Performance Architecture

sr is optimized for performance through:

  1. Lazy Evaluation: Only process files that match patterns
  2. Batch Operations: Minimize tool invocations
  3. Stream Processing: Handle large files without loading into memory
  4. Parallel Safety: Safe for concurrent execution with separate sessions
# Performance optimization examples:
# 1. Use find with -print0 for null-terminated output
# 2. Process files in batches where appropriate
# 3. Cache file metadata to avoid repeated stat calls
# 4. Use efficient grep patterns for binary detection

Security Architecture

sr implements defense in depth:

  1. Input Validation:

    # Validate file paths
    if [[ "$path" == *".."* ]] || [[ "$path" == /proc/* ]]; then
        log_error "Dangerous path detected"
        return 1
    fi
  2. Permission Management:

    # Preserve original permissions
    cp --preserve=all "$original" "$backup"
  3. Session Isolation:

    # Each session is independent
    # No cross-session file access
  4. Cleanup Guarantees:

    # Temporary files always cleaned up
    trap 'cleanup_temp_files' EXIT

Extension Points

sr is designed for extensibility:

  1. Tool Integration:

    # Custom tool paths
    readonly FIND_TOOL="find"
    readonly SED_TOOL="sed"
    # Can be overridden for custom implementations
  2. Hook System (planned):

    # Pre/post processing hooks
    # (Future feature)
  3. Plugin Architecture (planned):

    # Custom processors for different file types
    # (Future feature)

Monitoring and Observability

sr provides multiple observability levels:

  1. Log Levels:

    ERROR > WARNING > INFO > VERBOSE > DEBUG
  2. Session Tracking:

    # Complete audit trail
    sr --rollback-list
  3. Performance Metrics:

    # Available in verbose/debug modes
    Files processed: 150
    Processing time: 2.3s
    Rate: 65.2 files/second

Compatibility Layers

sr maintains compatibility through:

  1. Tool Detection:

    # Detect GNU vs BSD sed
    if sed --version 2>/dev/null | grep -q "GNU"; then
        SED_INPLACE_FLAG="-i"
    else
        SED_INPLACE_FLAG="-i ''"
    fi
  2. Fallback Mechanisms:

    # If file utility not available, use grep only
    if ! command -v file >/dev/null; then
        BINARY_DETECTION_METHOD="grep_only"
    fi
  3. Path Handling:

    # Handle different path formats
    if command -v realpath >/dev/null; then
        absolute_path=$(realpath "$path")
    else
        # Fallback implementation
    fi

Future Architecture Directions

Planned architectural improvements:

  1. Parallel Processing: Concurrent file processing with configurable workers
  2. Distributed Sessions: Cross-machine session synchronization
  3. Plugin System: Extensible file type handlers
  4. REST API: HTTP interface for remote operations
  5. Database Backend: Alternative session storage

Understanding Through Examples

Simple Command Flow:

# User enters:
sr "*.txt" "hello" "world"

# What happens:
# 1. Parse: pattern="*.txt", search="hello", replace="world"
# 2. Session: Create session ID "20241222_150000_123456789"
# 3. Find: Locate all *.txt files (excluding backups)
# 4. Process: For each file, backup, replace "hello" with "world"
# 5. Finalize: Save metadata, show summary

Complex Command Flow:

sr -v -i -w -md 3 --find-opts="-type f -mtime -7" \
   "*.log" "error" "warning"

# What happens:
# 1. Parse all flags and options
# 2. Build custom find command with user options
# 3. Process with verbose logging, case-insensitive, word boundaries
# 4. Limit to 3 directory levels
# 5. Only process files modified in last 7 days

Debugging Architecture

To understand what sr is doing internally:

# Enable debug mode
sr -d "*.txt" "test" "TEST"

# Debug output shows:
# - Argument parsing steps
# - File discovery results
# - Binary detection decisions
# - Backup creation details
# - sed commands executed
# - Session tracking updates

Next Steps

Now that you understand the architecture:


This wiki is continuously updated. Contributions are welcome! See the Contributing Guide for details.

Clone this wiki locally