sr-search-replace 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +144 -0
- package/LICENSE +21 -0
- package/README.md +1951 -0
- package/bin/sr +37 -0
- package/package.json +61 -0
- package/scripts/install.js +40 -0
- package/sr.sh +4186 -0
package/README.md
ADDED
|
@@ -0,0 +1,1951 @@
|
|
|
1
|
+
# Search & Replace (sr) - Universal Text Replacement Utility v6.1.0
|
|
2
|
+
|
|
3
|
+
[](https://github.com/paulmann/sr-search-replace/releases/tag/v6.1.0)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://www.gnu.org/software/bash/)
|
|
6
|
+
[](#system-requirements)
|
|
7
|
+
[](#system-requirements)
|
|
8
|
+
[](#prerequisites)
|
|
9
|
+
[](https://github.com/paulmann/sr-search-replace)
|
|
10
|
+
|
|
11
|
+
> **Enterprise-grade search and replace utility with session-based rollback, multi-layer binary detection, and advanced backup management**
|
|
12
|
+
|
|
13
|
+
## Table of Contents
|
|
14
|
+
|
|
15
|
+
1. [Overview](#overview)
|
|
16
|
+
2. [Quick Start](#quick-start)
|
|
17
|
+
3. [What's New in v6.1.0](#whats-new-in-v610)
|
|
18
|
+
4. [Key Features](#key-features)
|
|
19
|
+
5. [System Requirements](#system-requirements)
|
|
20
|
+
6. [Installation](#installation)
|
|
21
|
+
7. [Usage Guide](#usage-guide)
|
|
22
|
+
8. [Configuration](#configuration)
|
|
23
|
+
9. [How It Works](#how-it-works)
|
|
24
|
+
10. [Workflow Examples](#workflow-examples)
|
|
25
|
+
11. [Enterprise Deployment](#enterprise-deployment)
|
|
26
|
+
12. [Advanced Scenarios](#advanced-scenarios)
|
|
27
|
+
13. [Troubleshooting](#troubleshooting)
|
|
28
|
+
14. [Performance Optimization](#performance-optimization)
|
|
29
|
+
15. [Security Considerations](#security-considerations)
|
|
30
|
+
16. [Version History](#version-history)
|
|
31
|
+
17. [Contributing](#contributing)
|
|
32
|
+
18. [License](#license)
|
|
33
|
+
19. [Support](#support)
|
|
34
|
+
20. [FAQ](#faq)
|
|
35
|
+
|
|
36
|
+
## Overview
|
|
37
|
+
|
|
38
|
+
`sr` is a professional-grade command-line utility designed for safe, predictable, and auditable text replacements across multiple files. Built with enterprise deployments in mind, it provides developers, system administrators, and DevOps engineers with a robust, production-ready replacement mechanism that eliminates common pitfalls associated with text manipulation.
|
|
39
|
+
|
|
40
|
+
Unlike simplistic alternatives like `sed -i` or basic find-replace scripts, `sr` implements a comprehensive safety-first approach with industrial-strength features including multi-layer binary file detection, session-based backup management with complete audit trails, one-command rollback capabilities, and configurable safety limits.
|
|
41
|
+
|
|
42
|
+
### Why Choose sr?
|
|
43
|
+
|
|
44
|
+
- **Safety First**: Multi-layer protection against accidental data corruption
|
|
45
|
+
- **Enterprise Ready**: Session tracking, audit trails, and configurable safety limits
|
|
46
|
+
- **Predictable Behavior**: Consistent argument parsing and explicit behavior control
|
|
47
|
+
- **Professional Tooling**: Direct parameter passing to core utilities (find/sed/grep)
|
|
48
|
+
- **Cross-Platform**: Compatible with Linux, macOS, and BSD systems
|
|
49
|
+
- **Comprehensive**: 40+ configuration options with environment variable support
|
|
50
|
+
|
|
51
|
+
## Quick Start
|
|
52
|
+
|
|
53
|
+
### Installation in 30 Seconds
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Download and install
|
|
57
|
+
curl -L https://raw.githubusercontent.com/paulmann/sr-search-replace/main/sr.sh -o sr
|
|
58
|
+
chmod +x sr
|
|
59
|
+
sudo mv sr /usr/local/bin/
|
|
60
|
+
|
|
61
|
+
# Verify installation
|
|
62
|
+
sr --version
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Basic Usage Examples
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Simple domain migration in HTML files
|
|
69
|
+
sr "*.html" "old-domain.com" "new-domain.com"
|
|
70
|
+
|
|
71
|
+
# Recursive replacement with case-insensitive matching
|
|
72
|
+
sr -i "*.js" "function oldName" "function newName"
|
|
73
|
+
|
|
74
|
+
# Test changes before applying (dry-run)
|
|
75
|
+
sr --dry-run "*.conf" "localhost:3000" "localhost:8080"
|
|
76
|
+
|
|
77
|
+
# Restore from accidental changes
|
|
78
|
+
sr --rollback
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Essential Safety Features
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Always test first
|
|
85
|
+
sr --dry-run -v "*.py" "deprecated_function" "new_function"
|
|
86
|
+
|
|
87
|
+
# Create backups automatically (default)
|
|
88
|
+
sr "*.sql" "DROP TABLE" "DELETE FROM"
|
|
89
|
+
|
|
90
|
+
# Restore if something goes wrong
|
|
91
|
+
sr --rollback
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## What's New in v6.1.0
|
|
95
|
+
|
|
96
|
+
### Enhanced Configuration System
|
|
97
|
+
|
|
98
|
+
Version 6.1.0 introduces a comprehensive configuration system with tool-specific parameter passing and extended search capabilities:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Tool-specific parameter passing (NEW)
|
|
102
|
+
sr --find-opts="-type f -mtime -7" "*.log" "ERROR" "WARNING"
|
|
103
|
+
sr --sed-opts="-e 's/foo/bar/' -e 's/baz/qux/'" "*.txt" "find" "replace"
|
|
104
|
+
sr --grep-opts="-v '^#'" "*.conf" "port" "8080"
|
|
105
|
+
|
|
106
|
+
# Extended search options (NEW)
|
|
107
|
+
sr -i -E -w "*.md" "\bAPI\b" "Application Programming Interface"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Key Enhancements
|
|
111
|
+
|
|
112
|
+
1. **Tool Configuration Variables**: Base tool commands and default flags configurable as script variables
|
|
113
|
+
2. **Direct Parameter Passing**: `--find-opts`, `--sed-opts`, `--grep-opts` flags for precise control
|
|
114
|
+
3. **Extended Search Capabilities**: Case-insensitive matching, word boundaries, extended regex
|
|
115
|
+
4. **Improved Compatibility**: Better handling of GNU/BSD sed variations
|
|
116
|
+
5. **Enhanced Documentation**: Complete reference for all tool-specific parameters
|
|
117
|
+
6. **Performance Optimizations**: Optimized flag handling and execution paths
|
|
118
|
+
|
|
119
|
+
### Backward Compatibility
|
|
120
|
+
|
|
121
|
+
Version 6.1.0 maintains full backward compatibility with v6.0.0. All existing scripts and workflows continue to work without modification.
|
|
122
|
+
|
|
123
|
+
## Key Features
|
|
124
|
+
|
|
125
|
+
### Core Functionality
|
|
126
|
+
|
|
127
|
+
#### 🔄 **Recursive File Processing**
|
|
128
|
+
- Recursive directory traversal with configurable depth limits (1-1000 levels)
|
|
129
|
+
- Single and multi-file processing modes with explicit file lists
|
|
130
|
+
- Support for shell glob patterns with proper escaping and quoting
|
|
131
|
+
- Dual-mode operation: pattern matching or explicit file list
|
|
132
|
+
- Predictable argument parsing eliminates confusion
|
|
133
|
+
|
|
134
|
+
#### 🔍 **Multi-Layer Binary Detection**
|
|
135
|
+
- Three detection methods: `multi_layer` (default), `file_only`, `grep_only`
|
|
136
|
+
- Layer 1: Fast grep heuristic on first N bytes (configurable)
|
|
137
|
+
- Layer 2: File utility MIME type analysis (when available)
|
|
138
|
+
- Layer 3: Combined decision with zero false positives
|
|
139
|
+
- Explicit `--binary` flag required for binary file processing
|
|
140
|
+
|
|
141
|
+
#### 💾 **Intelligent Backup System**
|
|
142
|
+
- Automatic backup creation before modifications (default)
|
|
143
|
+
- Session-based organization with unique session IDs (nanosecond precision)
|
|
144
|
+
- Complete metadata tracking: command, arguments, timestamps, user
|
|
145
|
+
- Real-time file tracking for accurate rollback operations
|
|
146
|
+
- Configurable retention policies (keep last N backups)
|
|
147
|
+
|
|
148
|
+
#### ⏮️ **Session Rollback System**
|
|
149
|
+
- One-command restoration: `sr --rollback`
|
|
150
|
+
- Specific session restoration: `sr --rollback=sr.backup.20240112_143022`
|
|
151
|
+
- Interactive confirmation with 30-second timeout
|
|
152
|
+
- Complete file restoration including permissions and ownership
|
|
153
|
+
- Detailed rollback status reporting with success/failure counts
|
|
154
|
+
|
|
155
|
+
#### 🔐 **Safety & Security Features**
|
|
156
|
+
- Dry-run mode for non-destructive testing (`--dry-run`)
|
|
157
|
+
- Maximum file size limits to prevent processing of huge files
|
|
158
|
+
- Automatic exclusion of dangerous directories (.git, node_modules, etc.)
|
|
159
|
+
- Hidden file filtering capability (`--exclude-hidden`)
|
|
160
|
+
- Configurable exclude patterns and directory lists
|
|
161
|
+
- Atomic operations with proper error handling and cleanup
|
|
162
|
+
|
|
163
|
+
### Enhanced Capabilities (v6.1.0)
|
|
164
|
+
|
|
165
|
+
#### 🛠️ **Tool-Specific Configuration**
|
|
166
|
+
```bash
|
|
167
|
+
# Base tool configuration (script variables)
|
|
168
|
+
FIND_TOOL="find"
|
|
169
|
+
SED_TOOL="sed"
|
|
170
|
+
GREP_TOOL="grep"
|
|
171
|
+
|
|
172
|
+
# Default flags configuration
|
|
173
|
+
FIND_FLAGS=""
|
|
174
|
+
SED_FLAGS=""
|
|
175
|
+
GREP_FLAGS="-F"
|
|
176
|
+
|
|
177
|
+
# Command-line overrides
|
|
178
|
+
sr --find-opts="-type f -name '*.js'" --sed-opts="-E" "*.js" "var " "let "
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
#### 🔍 **Extended Search Options**
|
|
182
|
+
- Case-insensitive matching (`-i, --ignore-case`)
|
|
183
|
+
- Extended regular expressions (`-E, --extended-regex`)
|
|
184
|
+
- Word boundary matching (`-w, --word-boundary`)
|
|
185
|
+
- Multi-line mode (`-m, --multiline`)
|
|
186
|
+
- Line number display (`-n, --line-numbers`)
|
|
187
|
+
- Dot matches newline (`--dot-all`)
|
|
188
|
+
- Global replace control (`--no-global`)
|
|
189
|
+
|
|
190
|
+
#### 📊 **Comprehensive Logging & Reporting**
|
|
191
|
+
- Four logging levels: error, warning, info, verbose, debug
|
|
192
|
+
- Color-coded output for better readability
|
|
193
|
+
- Session metadata tracking and reporting
|
|
194
|
+
- Detailed statistics: files processed, replacements made, performance metrics
|
|
195
|
+
- Progress reporting with time estimation for large file sets
|
|
196
|
+
|
|
197
|
+
#### ⚙️ **Flexible Configuration System**
|
|
198
|
+
- Environment variable overrides for all major options
|
|
199
|
+
- Configuration via script variables (editable header section)
|
|
200
|
+
- Command-line precedence: CLI > Environment > Script defaults
|
|
201
|
+
- Customizable delimiters for sed operations
|
|
202
|
+
- Configurable file encoding handling
|
|
203
|
+
|
|
204
|
+
## System Requirements
|
|
205
|
+
|
|
206
|
+
### Prerequisites
|
|
207
|
+
|
|
208
|
+
The tool requires a POSIX-compliant shell environment with standard GNU/BSD utilities:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
# Required core utilities (minimum versions)
|
|
212
|
+
bash (5.0 or higher) # Shell interpreter
|
|
213
|
+
find (4.0+) # File discovery
|
|
214
|
+
sed (4.0+) # Stream editor
|
|
215
|
+
grep (3.0+) # Pattern matching
|
|
216
|
+
|
|
217
|
+
# Highly recommended for enhanced functionality
|
|
218
|
+
file (5.0+) # Improved binary detection
|
|
219
|
+
stat (8.0+) # Ownership/permission preservation
|
|
220
|
+
touch (8.0+) # Timestamp management
|
|
221
|
+
realpath (8.0+) # Path resolution
|
|
222
|
+
|
|
223
|
+
# Optional for additional features
|
|
224
|
+
bc (1.0+) # Mathematical calculations
|
|
225
|
+
du (8.0+) # Disk usage reporting
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Compatibility Matrix
|
|
229
|
+
|
|
230
|
+
| System | Version | Status | Notes |
|
|
231
|
+
|--------|---------|--------|-------|
|
|
232
|
+
| Ubuntu Linux | 18.04+ | ✅ Fully Compatible | All features supported |
|
|
233
|
+
| Debian | 10+ | ✅ Fully Compatible | Recommended for production |
|
|
234
|
+
| CentOS/RHEL | 7+ | ✅ Fully Compatible | May require GNU coreutils |
|
|
235
|
+
| macOS | 10.15+ | ✅ Fully Compatible | BSD sed requires GNU sed for some features |
|
|
236
|
+
| Alpine Linux | 3.14+ | ⚠️ Mostly Compatible | BusyBox limitations may apply |
|
|
237
|
+
| FreeBSD | 12.0+ | ⚠️ Mostly Compatible | Different tool flags |
|
|
238
|
+
| Windows WSL2 | All | ✅ Fully Compatible | Linux subsystem required |
|
|
239
|
+
|
|
240
|
+
### Dependencies Installation
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Ubuntu/Debian
|
|
244
|
+
sudo apt-get update
|
|
245
|
+
sudo apt-get install bash findutils sed grep file coreutils
|
|
246
|
+
|
|
247
|
+
# RHEL/CentOS
|
|
248
|
+
sudo yum install bash findutils sed grep file coreutils
|
|
249
|
+
|
|
250
|
+
# macOS (Homebrew)
|
|
251
|
+
brew install bash findutils gnu-sed grep file coreutils
|
|
252
|
+
brew link --force gnu-sed
|
|
253
|
+
|
|
254
|
+
# Alpine Linux
|
|
255
|
+
apk add bash findutils sed grep file coreutils
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Installation
|
|
259
|
+
|
|
260
|
+
### Method 1: Direct Download (Recommended)
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# Download latest version
|
|
264
|
+
curl -L https://raw.githubusercontent.com/paulmann/sr-search-replace/main/sr.sh -o sr
|
|
265
|
+
|
|
266
|
+
# Make executable
|
|
267
|
+
chmod +x sr
|
|
268
|
+
|
|
269
|
+
# Install globally (optional)
|
|
270
|
+
sudo cp sr /usr/local/bin/
|
|
271
|
+
|
|
272
|
+
# Verify installation
|
|
273
|
+
sr --version
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Method 2: Git Clone (Development)
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Clone repository
|
|
280
|
+
git clone https://github.com/paulmann/sr-search-replace.git
|
|
281
|
+
cd sr-search-replace
|
|
282
|
+
|
|
283
|
+
# Make executable
|
|
284
|
+
chmod +x sr.sh
|
|
285
|
+
|
|
286
|
+
# Create symlink
|
|
287
|
+
sudo ln -s "$(pwd)/sr.sh" /usr/local/bin/sr
|
|
288
|
+
|
|
289
|
+
# Test installation
|
|
290
|
+
sr --help
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Method 3: Package Manager (Advanced)
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
# Create installation package (deb/rpm)
|
|
297
|
+
# Example for Debian-based systems
|
|
298
|
+
mkdir -p sr-package/usr/local/bin
|
|
299
|
+
cp sr.sh sr-package/usr/local/bin/sr
|
|
300
|
+
chmod +x sr-package/usr/local/bin/sr
|
|
301
|
+
|
|
302
|
+
# Build package (requires dpkg-deb)
|
|
303
|
+
dpkg-deb --build sr-package sr_6.1.0_all.deb
|
|
304
|
+
sudo dpkg -i sr_6.1.0_all.deb
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Installation Verification
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
# Test all components
|
|
311
|
+
sr --version
|
|
312
|
+
sr --help | head -20
|
|
313
|
+
|
|
314
|
+
# Verify tool dependencies
|
|
315
|
+
for cmd in bash find sed grep file stat; do
|
|
316
|
+
if command -v $cmd >/dev/null 2>&1; then
|
|
317
|
+
echo "✓ $cmd: $(which $cmd)"
|
|
318
|
+
else
|
|
319
|
+
echo "✗ $cmd: NOT FOUND"
|
|
320
|
+
fi
|
|
321
|
+
done
|
|
322
|
+
|
|
323
|
+
# Run diagnostic test
|
|
324
|
+
sr --dry-run "*.txt" "test" "TEST" 2>&1 | grep -i "dry-run"
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Upgrading from Previous Versions
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
# Backup existing configuration if any
|
|
331
|
+
cp ~/.sr_config ~/.sr_config.backup 2>/dev/null || true
|
|
332
|
+
|
|
333
|
+
# Download and replace
|
|
334
|
+
curl -L https://raw.githubusercontent.com/paulmann/sr-search-replace/main/sr.sh -o /tmp/sr_new
|
|
335
|
+
chmod +x /tmp/sr_new
|
|
336
|
+
|
|
337
|
+
# Test new version
|
|
338
|
+
/tmp/sr_new --version
|
|
339
|
+
|
|
340
|
+
# Replace if tests pass
|
|
341
|
+
sudo cp /tmp/sr_new /usr/local/bin/sr
|
|
342
|
+
sr --version
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Usage Guide
|
|
346
|
+
|
|
347
|
+
### Command Syntax
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
# Basic syntax
|
|
351
|
+
sr [OPTIONS] "FILE_PATTERN" "SEARCH_STRING" "REPLACE_STRING"
|
|
352
|
+
|
|
353
|
+
# Important: Options MUST come before positional arguments
|
|
354
|
+
# Correct:
|
|
355
|
+
sr -v --dry-run "*.html" "old" "new"
|
|
356
|
+
|
|
357
|
+
# Incorrect (won't work as expected):
|
|
358
|
+
sr "*.html" "old" "new" -v --dry-run
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Argument Processing Modes
|
|
362
|
+
|
|
363
|
+
`sr` supports three distinct argument processing modes:
|
|
364
|
+
|
|
365
|
+
#### Mode 1: Standard 3-Argument (Recommended)
|
|
366
|
+
```bash
|
|
367
|
+
sr "PATTERN" "SEARCH" "REPLACE"
|
|
368
|
+
# Example: sr "*.js" "function old" "function new"
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
#### Mode 2: Standard 2-Argument (Default Pattern)
|
|
372
|
+
```bash
|
|
373
|
+
sr "SEARCH" "REPLACE"
|
|
374
|
+
# Uses default pattern: *.*
|
|
375
|
+
# Example: sr "localhost" "production-host"
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
#### Mode 3: Explicit File List (Shell Expansion)
|
|
379
|
+
```bash
|
|
380
|
+
sr file1.txt file2.txt "SEARCH" "REPLACE"
|
|
381
|
+
# Process specific files (not patterns)
|
|
382
|
+
# Example: sr index.html about.html "Copyright 2020" "Copyright 2025"
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Essential Options Quick Reference
|
|
386
|
+
|
|
387
|
+
| Category | Option | Description |
|
|
388
|
+
|----------|--------|-------------|
|
|
389
|
+
| **Core** | `-v, --verbose` | Enable verbose output |
|
|
390
|
+
| | `-d, --debug` | Enable debug output (implies verbose) |
|
|
391
|
+
| | `-nr, --no-recursive` | Non-recursive search |
|
|
392
|
+
| **Safety** | `--dry-run` | Test without modifications |
|
|
393
|
+
| | `--binary` | Allow binary file processing (REQUIRED) |
|
|
394
|
+
| | `-nb, --no-backup` | Disable backup creation |
|
|
395
|
+
| **Search** | `-i, --ignore-case` | Case-insensitive search |
|
|
396
|
+
| | `-E, --extended-regex` | Use extended regular expressions |
|
|
397
|
+
| | `-w, --word-boundary` | Match whole words only |
|
|
398
|
+
| **Tools** | `--find-opts="FLAGS"` | Additional flags for find |
|
|
399
|
+
| | `--sed-opts="FLAGS"` | Additional flags for sed |
|
|
400
|
+
| | `--grep-opts="FLAGS"` | Additional flags for grep |
|
|
401
|
+
| **Rollback** | `--rollback` | Restore latest backup |
|
|
402
|
+
| | `--rollback-list` | List available backups |
|
|
403
|
+
|
|
404
|
+
### Comprehensive Examples
|
|
405
|
+
|
|
406
|
+
#### Basic Text Replacement
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
# Simple string replacement
|
|
410
|
+
sr "*.txt" "hello" "world"
|
|
411
|
+
|
|
412
|
+
# Recursive replacement with verbose output
|
|
413
|
+
sr -v "**/*.js" "var " "const "
|
|
414
|
+
|
|
415
|
+
# Case-insensitive domain migration
|
|
416
|
+
sr -i "*.html" "http://example.com" "https://example.com"
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
#### Pattern-Based Operations
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
# Replace in specific file types only
|
|
423
|
+
sr "src/**/*.ts" "interface Old" "interface New"
|
|
424
|
+
|
|
425
|
+
# Multiple file patterns (using shell expansion)
|
|
426
|
+
sr *.js *.ts *.jsx "React.Component" "React.PureComponent"
|
|
427
|
+
|
|
428
|
+
# Exclude directories from search
|
|
429
|
+
sr -xd node_modules,dist "*.js" "TODO:" "DONE:"
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
#### Advanced Search Features
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
# Extended regex with word boundaries
|
|
436
|
+
sr -E -w "*.md" "\bAPI\b" "Application Programming Interface"
|
|
437
|
+
|
|
438
|
+
# Case-insensitive multi-line replacement
|
|
439
|
+
sr -i -m "*.py" "def calculate.*\n.*return" "def compute"
|
|
440
|
+
|
|
441
|
+
# Show line numbers of matches (dry-run)
|
|
442
|
+
sr --dry-run -n "*.java" "System.out.println" "logger.debug"
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
#### Safety-First Operations
|
|
446
|
+
|
|
447
|
+
```bash
|
|
448
|
+
# Always test first with dry-run
|
|
449
|
+
sr --dry-run -v "*.yml" "password:.*" "password: [REDACTED]"
|
|
450
|
+
|
|
451
|
+
# Force backups for critical changes
|
|
452
|
+
sr -fb "*.sql" "DROP TABLE" "-- DROP TABLE"
|
|
453
|
+
|
|
454
|
+
# Set safe limits for production
|
|
455
|
+
sr -md 5 -xs 10 "*.conf" "debug: true" "debug: false"
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
#### Tool-Specific Parameter Passing (v6.1.0)
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
# Pass custom flags to find
|
|
462
|
+
sr --find-opts="-type f -mtime -1" "*.log" "ERROR" "WARNING"
|
|
463
|
+
|
|
464
|
+
# Use sed with multiple expressions
|
|
465
|
+
sr --sed-opts="-e 's/foo/bar/g' -e 's/baz/qux/g'" "*.txt" "pattern" "replacement"
|
|
466
|
+
|
|
467
|
+
# Configure grep behavior
|
|
468
|
+
sr --grep-opts="-v '^#'" "*.conf" "port = 3000" "port = 8080"
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
#### Session Management and Rollback
|
|
472
|
+
|
|
473
|
+
```bash
|
|
474
|
+
# List all available backups
|
|
475
|
+
sr --rollback-list
|
|
476
|
+
|
|
477
|
+
# Restore latest backup
|
|
478
|
+
sr --rollback
|
|
479
|
+
|
|
480
|
+
# Restore specific session
|
|
481
|
+
sr --rollback=sr.backup.20240115_143022_123456789
|
|
482
|
+
|
|
483
|
+
# Interactive restoration with timeout
|
|
484
|
+
echo "y" | timeout 10 sr --rollback
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Exit Codes
|
|
488
|
+
|
|
489
|
+
| Code | Meaning | Typical Scenario |
|
|
490
|
+
|------|---------|------------------|
|
|
491
|
+
| 0 | Success | Replacements completed successfully |
|
|
492
|
+
| 1 | Invalid arguments | Missing or incorrect parameters |
|
|
493
|
+
| 2 | No files found | Pattern didn't match any files |
|
|
494
|
+
| 3 | No replacements | Search string not found |
|
|
495
|
+
| 4 | Runtime error | Permission issues, disk full, etc. |
|
|
496
|
+
| 5 | Backup failed | Couldn't create backup files |
|
|
497
|
+
| 6 | Binary file detected | Binary file encountered without --binary flag |
|
|
498
|
+
| 7 | Rollback failed | Restoration encountered errors |
|
|
499
|
+
|
|
500
|
+
## Configuration
|
|
501
|
+
|
|
502
|
+
### Environment Variables
|
|
503
|
+
|
|
504
|
+
Configure default behavior via environment variables (override script defaults):
|
|
505
|
+
|
|
506
|
+
```bash
|
|
507
|
+
# Core behavior
|
|
508
|
+
export SR_DEBUG=true
|
|
509
|
+
export SR_DRY_RUN=false
|
|
510
|
+
export SR_NO_BACKUP=false
|
|
511
|
+
export SR_FORCE_BACKUP=false
|
|
512
|
+
export SR_MAX_DEPTH=50
|
|
513
|
+
export SR_VERBOSE=true
|
|
514
|
+
|
|
515
|
+
# Safety limits
|
|
516
|
+
export SR_MAX_FILE_SIZE_MB=50
|
|
517
|
+
export SR_BINARY_CHECK_SIZE=2048
|
|
518
|
+
export SR_MAX_BACKUPS=20
|
|
519
|
+
|
|
520
|
+
# Search behavior (v6.1.0)
|
|
521
|
+
export SR_IGNORE_CASE=false
|
|
522
|
+
export SR_EXTENDED_REGEX=true
|
|
523
|
+
export SR_WORD_BOUNDARY=false
|
|
524
|
+
export SR_GLOBAL_REPLACE=true
|
|
525
|
+
|
|
526
|
+
# Tool configuration (v6.1.0)
|
|
527
|
+
export SR_FIND_FLAGS="-type f"
|
|
528
|
+
export SR_SED_FLAGS=""
|
|
529
|
+
export SR_GREP_FLAGS="-F"
|
|
530
|
+
|
|
531
|
+
# Execution
|
|
532
|
+
sr "*.conf" "old" "new"
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
### Script Configuration Header
|
|
536
|
+
|
|
537
|
+
Advanced users can modify default behavior directly in the script header:
|
|
538
|
+
|
|
539
|
+
```bash
|
|
540
|
+
# ============================================================================
|
|
541
|
+
# ENHANCED CONFIGURABLE DEFAULTS - EDIT THESE TO CHANGE SCRIPT BEHAVIOR
|
|
542
|
+
# ============================================================================
|
|
543
|
+
|
|
544
|
+
# Default behavior settings
|
|
545
|
+
readonly SESSION_VERSION="6.1.0"
|
|
546
|
+
readonly DEFAULT_DEBUG_MODE=false
|
|
547
|
+
readonly DEFAULT_RECURSIVE_MODE=true
|
|
548
|
+
readonly DEFAULT_DRY_RUN=false
|
|
549
|
+
|
|
550
|
+
# Tool configuration (v6.1.0)
|
|
551
|
+
readonly FIND_TOOL="find"
|
|
552
|
+
readonly SED_TOOL="sed"
|
|
553
|
+
readonly GREP_TOOL="grep"
|
|
554
|
+
readonly DEFAULT_FIND_FLAGS=""
|
|
555
|
+
readonly DEFAULT_SED_FLAGS=""
|
|
556
|
+
readonly DEFAULT_GREP_FLAGS="-F"
|
|
557
|
+
|
|
558
|
+
# Enhanced search parameters (v6.1.0)
|
|
559
|
+
readonly DEFAULT_IGNORE_CASE=false
|
|
560
|
+
readonly DEFAULT_EXTENDED_REGEX=false
|
|
561
|
+
readonly DEFAULT_WORD_BOUNDARY=false
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### Configuration Precedence
|
|
565
|
+
|
|
566
|
+
1. **Command-line arguments** (highest priority)
|
|
567
|
+
2. **Environment variables** (SR_*)
|
|
568
|
+
3. **Script defaults** (lowest priority)
|
|
569
|
+
|
|
570
|
+
Example:
|
|
571
|
+
```bash
|
|
572
|
+
# Script default: DEFAULT_MAX_DEPTH=100
|
|
573
|
+
# Environment: SR_MAX_DEPTH=50
|
|
574
|
+
# Command line: -md 10
|
|
575
|
+
# Result: MAX_DEPTH=10 (command line wins)
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### Persistent Configuration
|
|
579
|
+
|
|
580
|
+
For team or project-specific settings, create a configuration wrapper:
|
|
581
|
+
|
|
582
|
+
```bash
|
|
583
|
+
#!/bin/bash
|
|
584
|
+
# File: /usr/local/bin/sr-project
|
|
585
|
+
export SR_MAX_DEPTH=3
|
|
586
|
+
export SR_NO_BACKUP=false
|
|
587
|
+
export SR_VERBOSE=true
|
|
588
|
+
export SR_EXCLUDE_DIRS="node_modules,dist,.git"
|
|
589
|
+
/usr/local/bin/sr "$@"
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
## How It Works
|
|
593
|
+
|
|
594
|
+
### Architecture Overview
|
|
595
|
+
|
|
596
|
+
```mermaid
|
|
597
|
+
graph TB
|
|
598
|
+
A[Start sr.sh] --> B[Parse Arguments]
|
|
599
|
+
B --> C{Argument Analysis}
|
|
600
|
+
C -->|3 args| D[Pattern Mode]
|
|
601
|
+
C -->|2 args| E[Default Pattern]
|
|
602
|
+
C -->|>3 args| F[Explicit File List]
|
|
603
|
+
|
|
604
|
+
D --> G[File Discovery]
|
|
605
|
+
E --> G
|
|
606
|
+
F --> H[File Validation]
|
|
607
|
+
|
|
608
|
+
G --> I[Apply Filters]
|
|
609
|
+
H --> I
|
|
610
|
+
|
|
611
|
+
I --> J[Process Each File]
|
|
612
|
+
|
|
613
|
+
J --> K{Binary Check?}
|
|
614
|
+
K -->|Yes| L[Multi-layer Detection]
|
|
615
|
+
K -->|No| M[Skip Check]
|
|
616
|
+
|
|
617
|
+
L --> N{Binary?}
|
|
618
|
+
N -->|Yes| O{--binary flag?}
|
|
619
|
+
N -->|No| P[Continue]
|
|
620
|
+
|
|
621
|
+
O -->|Yes| P
|
|
622
|
+
O -->|No| Q[Skip File]
|
|
623
|
+
|
|
624
|
+
P --> R[Create Backup]
|
|
625
|
+
R --> S[Perform Replacement]
|
|
626
|
+
S --> T[Track Changes]
|
|
627
|
+
|
|
628
|
+
T --> U{More files?}
|
|
629
|
+
U -->|Yes| J
|
|
630
|
+
U -->|No| V[Finalize Session]
|
|
631
|
+
|
|
632
|
+
V --> W[Update Metadata]
|
|
633
|
+
W --> X[Cleanup Old Backups]
|
|
634
|
+
X --> Y[Show Summary]
|
|
635
|
+
Y --> Z[End]
|
|
636
|
+
|
|
637
|
+
Q --> U
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
### Session Management System
|
|
641
|
+
|
|
642
|
+
Each execution creates a unique session with comprehensive tracking:
|
|
643
|
+
|
|
644
|
+
```
|
|
645
|
+
sr.backup.20240115_143022_123456789/
|
|
646
|
+
├── .sr_session_metadata # Complete session information
|
|
647
|
+
│ ├── SESSION_ID
|
|
648
|
+
│ ├── SESSION_COMMAND
|
|
649
|
+
│ ├── SESSION_START_TIME
|
|
650
|
+
│ ├── SESSION_END_TIME
|
|
651
|
+
│ ├── SESSION_MODIFIED_COUNT
|
|
652
|
+
│ └── SESSION_TOTAL_REPLACEMENTS
|
|
653
|
+
├── .sr_modified_files # List of modified files
|
|
654
|
+
├── .sr_file_info # Additional file metadata
|
|
655
|
+
└── files/ # Original file backups
|
|
656
|
+
├── index.html
|
|
657
|
+
├── config.json
|
|
658
|
+
└── src/main.js
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### File Processing Pipeline
|
|
662
|
+
|
|
663
|
+
```mermaid
|
|
664
|
+
sequenceDiagram
|
|
665
|
+
participant User
|
|
666
|
+
participant SR as sr.sh
|
|
667
|
+
participant Find as find/grep
|
|
668
|
+
participant FileSys as File System
|
|
669
|
+
participant Backup as Backup System
|
|
670
|
+
participant Sed as sed
|
|
671
|
+
|
|
672
|
+
User->>SR: Execute with arguments
|
|
673
|
+
SR->>Find: Discover files
|
|
674
|
+
Find->>FileSys: Match patterns
|
|
675
|
+
FileSys->>Find: Return file list
|
|
676
|
+
Find->>SR: Filtered files
|
|
677
|
+
|
|
678
|
+
loop For Each File
|
|
679
|
+
SR->>SR: Binary detection
|
|
680
|
+
SR->>Backup: Create backup
|
|
681
|
+
Backup->>FileSys: Copy original
|
|
682
|
+
SR->>Sed: Perform replacement
|
|
683
|
+
Sed->>FileSys: Modify file
|
|
684
|
+
SR->>SR: Track changes
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
SR->>SR: Finalize session
|
|
688
|
+
SR->>User: Show summary
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
### Binary File Detection Flow
|
|
692
|
+
|
|
693
|
+
```mermaid
|
|
694
|
+
flowchart TD
|
|
695
|
+
A[Start Binary Check] --> B{Layer 1: Size Check}
|
|
696
|
+
B -->|Empty| C[Not Binary]
|
|
697
|
+
B -->|Has content| D{Layer 2: Grep Heuristic}
|
|
698
|
+
|
|
699
|
+
D -->|Non-text chars| E{Layer 3: File Utility}
|
|
700
|
+
D -->|Text only| C
|
|
701
|
+
|
|
702
|
+
E -->|MIME: text/*| C
|
|
703
|
+
E -->|MIME: other| F[Binary Detected]
|
|
704
|
+
E -->|No file command| G{Fallback Decision}
|
|
705
|
+
|
|
706
|
+
G -->|Grep says binary| F
|
|
707
|
+
G -->|Grep says text| C
|
|
708
|
+
|
|
709
|
+
F --> H{--binary flag?}
|
|
710
|
+
H -->|Yes| I[Allow Processing]
|
|
711
|
+
H -->|No| J[Skip File]
|
|
712
|
+
|
|
713
|
+
C --> K[Allow Processing]
|
|
714
|
+
I --> K
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### Multi-Layer Detection Details
|
|
718
|
+
|
|
719
|
+
1. **Layer 1 (Size Check)**: Empty files are considered text
|
|
720
|
+
2. **Layer 2 (Grep Heuristic)**: Check first N bytes (default: 1024) for non-text characters
|
|
721
|
+
3. **Layer 3 (File Utility)**: Use `file --mime-type` for authoritative classification
|
|
722
|
+
4. **Decision Logic**: Conservative approach - only classify as binary with high confidence
|
|
723
|
+
|
|
724
|
+
## Workflow Examples
|
|
725
|
+
|
|
726
|
+
### Development Workflow
|
|
727
|
+
|
|
728
|
+
```bash
|
|
729
|
+
# 1. Initial discovery and testing
|
|
730
|
+
sr --dry-run -v "src/**/*.ts" "anyFunction" "specificFunction"
|
|
731
|
+
|
|
732
|
+
# 2. Review what will be changed
|
|
733
|
+
sr --dry-run -n "src/**/*.ts" "anyFunction" "specificFunction" | head -20
|
|
734
|
+
|
|
735
|
+
# 3. Execute with backups
|
|
736
|
+
sr -v "src/**/*.ts" "anyFunction" "specificFunction"
|
|
737
|
+
|
|
738
|
+
# 4. Verify changes
|
|
739
|
+
git diff
|
|
740
|
+
|
|
741
|
+
# 5. Rollback if needed
|
|
742
|
+
sr --rollback
|
|
743
|
+
|
|
744
|
+
# 6. Clean up old backups
|
|
745
|
+
sr --max-backups=5 "dummy" "dummy" "dummy"
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
### Code Refactoring Workflow
|
|
749
|
+
|
|
750
|
+
```bash
|
|
751
|
+
# Refactor with confidence using session tracking
|
|
752
|
+
SESSION_ID=$(date +%Y%m%d_%H%M%S)_refactor
|
|
753
|
+
|
|
754
|
+
# Phase 1: Rename variables
|
|
755
|
+
sr --verbose "src/**/*.js" "var oldName" "const newName"
|
|
756
|
+
|
|
757
|
+
# Phase 2: Update function calls
|
|
758
|
+
sr --verbose "src/**/*.js" "oldFunction(" "newFunction("
|
|
759
|
+
|
|
760
|
+
# Phase 3: Update imports
|
|
761
|
+
sr --verbose "src/**/*.js" "from 'old-module'" "from 'new-module'"
|
|
762
|
+
|
|
763
|
+
# Verify all changes
|
|
764
|
+
sr --rollback-list
|
|
765
|
+
|
|
766
|
+
# Create checkpoint
|
|
767
|
+
echo "Refactoring checkpoint: $SESSION_ID"
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
### Configuration Management Workflow
|
|
771
|
+
|
|
772
|
+
```bash
|
|
773
|
+
# Update configuration across environments
|
|
774
|
+
for env in dev staging prod; do
|
|
775
|
+
echo "Processing $env environment..."
|
|
776
|
+
cd "/etc/app/$env"
|
|
777
|
+
|
|
778
|
+
# Backup current state
|
|
779
|
+
sr --verbose "*.conf" "dummy" "dummy" # Creates backup session
|
|
780
|
+
|
|
781
|
+
# Update configuration
|
|
782
|
+
sr --verbose "*.conf" "db.host=localhost" "db.host=cluster-$env"
|
|
783
|
+
sr --verbose "*.conf" "cache.enabled=false" "cache.enabled=true"
|
|
784
|
+
|
|
785
|
+
# Verify changes
|
|
786
|
+
sr --rollback-list | tail -5
|
|
787
|
+
|
|
788
|
+
echo "Completed $env"
|
|
789
|
+
done
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
### Emergency Rollback Procedure
|
|
793
|
+
|
|
794
|
+
```bash
|
|
795
|
+
# 1. Identify the problem
|
|
796
|
+
sr --rollback-list
|
|
797
|
+
|
|
798
|
+
# 2. Choose restoration point
|
|
799
|
+
BACKUP_DIR=$(sr --rollback-list 2>&1 | grep "sr.backup" | head -1 | awk '{print $1}')
|
|
800
|
+
|
|
801
|
+
# 3. Preview restoration
|
|
802
|
+
sr --dry-run --rollback="$BACKUP_DIR"
|
|
803
|
+
|
|
804
|
+
# 4. Execute restoration
|
|
805
|
+
sr --rollback="$BACKUP_DIR"
|
|
806
|
+
|
|
807
|
+
# 5. Verify restoration
|
|
808
|
+
echo "Restoration complete. Checking critical files..."
|
|
809
|
+
for file in /etc/app/config.json /var/www/index.html; do
|
|
810
|
+
if [[ -f "$file" ]]; then
|
|
811
|
+
echo "✓ $file exists"
|
|
812
|
+
fi
|
|
813
|
+
done
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
## Enterprise Deployment
|
|
817
|
+
|
|
818
|
+
### Security Hardening
|
|
819
|
+
|
|
820
|
+
```bash
|
|
821
|
+
#!/bin/bash
|
|
822
|
+
# File: sr-secure-wrapper.sh
|
|
823
|
+
# Enterprise security wrapper for sr.sh
|
|
824
|
+
|
|
825
|
+
# Set secure defaults
|
|
826
|
+
export SR_MAX_DEPTH=10
|
|
827
|
+
export SR_MAX_FILE_SIZE_MB=10
|
|
828
|
+
export SR_NO_BACKUP=false
|
|
829
|
+
export SR_FORCE_BACKUP=true
|
|
830
|
+
export SR_MAX_BACKUPS=30
|
|
831
|
+
export SR_BINARY_CHECK_SIZE=4096
|
|
832
|
+
|
|
833
|
+
# Exclude sensitive directories
|
|
834
|
+
export SR_EXCLUDE_DIRS=".git,node_modules,dist,build,.cache,.env,secrets"
|
|
835
|
+
|
|
836
|
+
# Limit binary processing
|
|
837
|
+
export SR_ALLOW_BINARY=false
|
|
838
|
+
export SR_BINARY_DETECTION_METHOD="multi_layer"
|
|
839
|
+
|
|
840
|
+
# Enable comprehensive logging
|
|
841
|
+
export SR_VERBOSE=true
|
|
842
|
+
|
|
843
|
+
# Execute with additional security checks
|
|
844
|
+
if [[ "$1" == "--rollback" ]]; then
|
|
845
|
+
# Additional authentication for rollbacks
|
|
846
|
+
echo "Rollback requested. Please authenticate:"
|
|
847
|
+
read -s -p "Security Token: " token
|
|
848
|
+
if [[ "$token" != "$SECURITY_TOKEN" ]]; then
|
|
849
|
+
echo "Authentication failed"
|
|
850
|
+
exit 1
|
|
851
|
+
fi
|
|
852
|
+
fi
|
|
853
|
+
|
|
854
|
+
# Execute original sr.sh
|
|
855
|
+
/usr/local/bin/sr "$@"
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
### Centralized Logging Integration
|
|
859
|
+
|
|
860
|
+
```bash
|
|
861
|
+
#!/bin/bash
|
|
862
|
+
# File: sr-logger.sh
|
|
863
|
+
# Wrapper for centralized logging
|
|
864
|
+
|
|
865
|
+
LOG_FILE="/var/log/sr-operations.log"
|
|
866
|
+
AUDIT_FILE="/var/log/sr-audit.log"
|
|
867
|
+
|
|
868
|
+
log_operation() {
|
|
869
|
+
local user=$(whoami)
|
|
870
|
+
local host=$(hostname)
|
|
871
|
+
local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
872
|
+
local session="${SESSION_ID:-unknown}"
|
|
873
|
+
|
|
874
|
+
echo "$timestamp | $user@$host | $session | $*" >> "$LOG_FILE"
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
log_audit() {
|
|
878
|
+
local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
879
|
+
local action="$1"
|
|
880
|
+
local details="$2"
|
|
881
|
+
|
|
882
|
+
echo "$timestamp | AUDIT | $action | $details" >> "$AUDIT_FILE"
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
# Log startup
|
|
886
|
+
log_operation "START: $0 $*"
|
|
887
|
+
|
|
888
|
+
# Execute and capture output
|
|
889
|
+
exec 5>&1
|
|
890
|
+
output=$(/usr/local/bin/sr "$@" 2>&1 | tee /dev/fd/5)
|
|
891
|
+
exit_code=$?
|
|
892
|
+
|
|
893
|
+
# Log completion
|
|
894
|
+
log_operation "END: exit_code=$exit_code"
|
|
895
|
+
log_audit "EXECUTION" "Command: $* | Exit: $exit_code"
|
|
896
|
+
|
|
897
|
+
exit $exit_code
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
### High Availability Configuration
|
|
901
|
+
|
|
902
|
+
```bash
|
|
903
|
+
# Distributed backup strategy
|
|
904
|
+
#!/bin/bash
|
|
905
|
+
# File: sr-ha.sh
|
|
906
|
+
# High availability wrapper with remote backup
|
|
907
|
+
|
|
908
|
+
PRIMARY_BACKUP_DIR="./backups"
|
|
909
|
+
SECONDARY_BACKUP_DIR="/mnt/backup-fs/sr-backups"
|
|
910
|
+
REMOTE_BACKUP_HOST="backup-server"
|
|
911
|
+
REMOTE_BACKUP_PATH="/backups/sr"
|
|
912
|
+
|
|
913
|
+
# Create local backup
|
|
914
|
+
/usr/local/bin/sr "$@"
|
|
915
|
+
EXIT_CODE=$?
|
|
916
|
+
|
|
917
|
+
if [[ $EXIT_CODE -eq 0 ]]; then
|
|
918
|
+
# Sync to secondary location
|
|
919
|
+
LATEST_BACKUP=$(ls -td sr.backup.* 2>/dev/null | head -1)
|
|
920
|
+
|
|
921
|
+
if [[ -n "$LATEST_BACKUP" ]]; then
|
|
922
|
+
# Copy to secondary FS
|
|
923
|
+
cp -r "$LATEST_BACKUP" "$SECONDARY_BACKUP_DIR/"
|
|
924
|
+
|
|
925
|
+
# Sync to remote (if configured)
|
|
926
|
+
if [[ -n "$REMOTE_BACKUP_HOST" ]]; then
|
|
927
|
+
rsync -avz "$LATEST_BACKUP/" \
|
|
928
|
+
"$REMOTE_BACKUP_HOST:$REMOTE_BACKUP_PATH/$LATEST_BACKUP/"
|
|
929
|
+
fi
|
|
930
|
+
|
|
931
|
+
echo "Backup replicated to secondary storage"
|
|
932
|
+
fi
|
|
933
|
+
fi
|
|
934
|
+
|
|
935
|
+
exit $EXIT_CODE
|
|
936
|
+
```
|
|
937
|
+
|
|
938
|
+
### Kubernetes/Container Deployment
|
|
939
|
+
|
|
940
|
+
```yaml
|
|
941
|
+
# File: sr-configmap.yaml
|
|
942
|
+
apiVersion: v1
|
|
943
|
+
kind: ConfigMap
|
|
944
|
+
metadata:
|
|
945
|
+
name: sr-config
|
|
946
|
+
data:
|
|
947
|
+
sr-config.sh: |
|
|
948
|
+
#!/bin/bash
|
|
949
|
+
export SR_MAX_DEPTH=20
|
|
950
|
+
export SR_MAX_FILE_SIZE_MB=50
|
|
951
|
+
export SR_NO_BACKUP=false
|
|
952
|
+
export SR_VERBOSE=true
|
|
953
|
+
export SR_EXCLUDE_DIRS=".git,node_modules"
|
|
954
|
+
export SR_BINARY_DETECTION_METHOD="multi_layer"
|
|
955
|
+
|
|
956
|
+
# Container-specific settings
|
|
957
|
+
export SR_SEARCH_DIR="/app"
|
|
958
|
+
export SR_TEMP_DIR="/tmp"
|
|
959
|
+
|
|
960
|
+
exec /usr/local/bin/sr "$@"
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
```dockerfile
|
|
964
|
+
# File: Dockerfile.sr
|
|
965
|
+
FROM alpine:3.14
|
|
966
|
+
|
|
967
|
+
# Install dependencies
|
|
968
|
+
RUN apk add --no-cache \
|
|
969
|
+
bash \
|
|
970
|
+
findutils \
|
|
971
|
+
sed \
|
|
972
|
+
grep \
|
|
973
|
+
file \
|
|
974
|
+
coreutils
|
|
975
|
+
|
|
976
|
+
# Install sr
|
|
977
|
+
COPY sr.sh /usr/local/bin/sr
|
|
978
|
+
RUN chmod +x /usr/local/bin/sr
|
|
979
|
+
|
|
980
|
+
# Create wrapper with defaults
|
|
981
|
+
COPY sr-config.sh /usr/local/bin/sr-wrapper
|
|
982
|
+
RUN chmod +x /usr/local/bin/sr-wrapper
|
|
983
|
+
|
|
984
|
+
ENTRYPOINT ["/usr/local/bin/sr-wrapper"]
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
## Advanced Scenarios
|
|
988
|
+
|
|
989
|
+
### Multi-Environment Synchronization
|
|
990
|
+
|
|
991
|
+
```bash
|
|
992
|
+
#!/bin/bash
|
|
993
|
+
# File: sync-environments.sh
|
|
994
|
+
# Synchronize configuration across multiple environments
|
|
995
|
+
|
|
996
|
+
ENVIRONMENTS="dev staging prod"
|
|
997
|
+
SEARCH_STRING="api.endpoint=http://localhost:8080"
|
|
998
|
+
REPLACE_TEMPLATE="api.endpoint=https://{env}-api.example.com"
|
|
999
|
+
|
|
1000
|
+
for env in $ENVIRONMENTS; do
|
|
1001
|
+
echo "=== Processing $env environment ==="
|
|
1002
|
+
|
|
1003
|
+
# Calculate environment-specific replacement
|
|
1004
|
+
REPLACE_STRING="${REPLACE_TEMPLATE/\{env\}/$env}"
|
|
1005
|
+
|
|
1006
|
+
# Change to environment directory
|
|
1007
|
+
cd "/opt/app/$env" || continue
|
|
1008
|
+
|
|
1009
|
+
# Create backup session
|
|
1010
|
+
BACKUP_SESSION="sync_$(date +%Y%m%d_%H%M%S)_$env"
|
|
1011
|
+
export SR_BACKUP_PREFIX="$BACKUP_SESSION"
|
|
1012
|
+
|
|
1013
|
+
# Perform replacement
|
|
1014
|
+
sr --verbose "*.json" "$SEARCH_STRING" "$REPLACE_STRING"
|
|
1015
|
+
|
|
1016
|
+
# Verify changes
|
|
1017
|
+
echo "Changes in $env:"
|
|
1018
|
+
grep -n "api.endpoint" *.json
|
|
1019
|
+
|
|
1020
|
+
# Log operation
|
|
1021
|
+
echo "$(date): $env updated" >> /var/log/config-sync.log
|
|
1022
|
+
|
|
1023
|
+
echo ""
|
|
1024
|
+
done
|
|
1025
|
+
```
|
|
1026
|
+
|
|
1027
|
+
### Database Migration Script Generation
|
|
1028
|
+
|
|
1029
|
+
```bash
|
|
1030
|
+
#!/bin/bash
|
|
1031
|
+
# File: generate-migrations.sh
|
|
1032
|
+
# Generate SQL migration scripts from configuration changes
|
|
1033
|
+
|
|
1034
|
+
# Extract database URLs from configuration
|
|
1035
|
+
sr --dry-run --verbose "*.yml" "database://" "DATABASE_PLACEHOLDER" | \
|
|
1036
|
+
grep -o "database://[^ ]*" | \
|
|
1037
|
+
sort -u > database-urls.txt
|
|
1038
|
+
|
|
1039
|
+
# Generate migration for each unique URL
|
|
1040
|
+
while read -r db_url; do
|
|
1041
|
+
# Parse URL components
|
|
1042
|
+
PROTOCOL="${db_url%://*}"
|
|
1043
|
+
REST="${db_url#*://}"
|
|
1044
|
+
USER_PASS="${REST%@*}"
|
|
1045
|
+
HOST_PORT="${REST#*@}"
|
|
1046
|
+
HOST="${HOST_PORT%:*}"
|
|
1047
|
+
PORT="${HOST_PORT#*:}"
|
|
1048
|
+
|
|
1049
|
+
# Generate migration script
|
|
1050
|
+
cat > "migrate_${HOST}.sql" << EOF
|
|
1051
|
+
-- Migration for ${HOST}
|
|
1052
|
+
-- Generated: $(date)
|
|
1053
|
+
-- Original URL: ${db_url}
|
|
1054
|
+
|
|
1055
|
+
-- Update connection strings
|
|
1056
|
+
UPDATE config SET value = '${db_url}' WHERE key = 'database.url';
|
|
1057
|
+
|
|
1058
|
+
-- Additional migration steps
|
|
1059
|
+
-- ... (add specific migration logic)
|
|
1060
|
+
EOF
|
|
1061
|
+
|
|
1062
|
+
echo "Generated migration for ${HOST}"
|
|
1063
|
+
done < database-urls.txt
|
|
1064
|
+
```
|
|
1065
|
+
|
|
1066
|
+
### Content Management System Updates
|
|
1067
|
+
|
|
1068
|
+
```bash
|
|
1069
|
+
#!/bin/bash
|
|
1070
|
+
# File: update-cms.sh
|
|
1071
|
+
# Batch update CMS content across multiple sites
|
|
1072
|
+
|
|
1073
|
+
SITES_DIR="/var/www/sites"
|
|
1074
|
+
PATTERNS=(
|
|
1075
|
+
"*.php"
|
|
1076
|
+
"*.html"
|
|
1077
|
+
"*.css"
|
|
1078
|
+
"*.js"
|
|
1079
|
+
)
|
|
1080
|
+
|
|
1081
|
+
# Common updates for CMS migration
|
|
1082
|
+
UPDATES=(
|
|
1083
|
+
"old-cdn.example.com|new-cdn.example.com"
|
|
1084
|
+
"http://|https://"
|
|
1085
|
+
"Copyright 2020|Copyright 2025"
|
|
1086
|
+
"jquery-1.11.1|jquery-3.6.0"
|
|
1087
|
+
)
|
|
1088
|
+
|
|
1089
|
+
for site in "$SITES_DIR"/*; do
|
|
1090
|
+
if [[ -d "$site" ]]; then
|
|
1091
|
+
SITE_NAME=$(basename "$site")
|
|
1092
|
+
echo "Updating site: $SITE_NAME"
|
|
1093
|
+
|
|
1094
|
+
cd "$site" || continue
|
|
1095
|
+
|
|
1096
|
+
for pattern in "${PATTERNS[@]}"; do
|
|
1097
|
+
for update in "${UPDATES[@]}"; do
|
|
1098
|
+
SEARCH="${update%|*}"
|
|
1099
|
+
REPLACE="${update#*|}"
|
|
1100
|
+
|
|
1101
|
+
# Dry-run first
|
|
1102
|
+
sr --dry-run --verbose "$pattern" "$SEARCH" "$REPLACE" | \
|
|
1103
|
+
tail -5
|
|
1104
|
+
|
|
1105
|
+
# Ask for confirmation
|
|
1106
|
+
read -p "Apply changes for '$SEARCH' -> '$REPLACE'? (y/n): " confirm
|
|
1107
|
+
if [[ "$confirm" == "y" ]]; then
|
|
1108
|
+
sr --verbose "$pattern" "$SEARCH" "$REPLACE"
|
|
1109
|
+
fi
|
|
1110
|
+
done
|
|
1111
|
+
done
|
|
1112
|
+
|
|
1113
|
+
echo "Completed $SITE_NAME"
|
|
1114
|
+
echo "---"
|
|
1115
|
+
fi
|
|
1116
|
+
done
|
|
1117
|
+
```
|
|
1118
|
+
|
|
1119
|
+
### Automated Code Review Cleanup
|
|
1120
|
+
|
|
1121
|
+
```bash
|
|
1122
|
+
#!/bin/bash
|
|
1123
|
+
# File: cleanup-code-review.sh
|
|
1124
|
+
# Automatically fix common code review comments
|
|
1125
|
+
|
|
1126
|
+
# Fix TODO comments
|
|
1127
|
+
sr --verbose "src/**/*.js" "// TODO:" "// TODO(username):"
|
|
1128
|
+
sr --verbose "src/**/*.js" "// FIXME:" "// FIXME(username):"
|
|
1129
|
+
|
|
1130
|
+
# Standardize error messages
|
|
1131
|
+
sr --verbose "src/**/*.js" "console.error('Error:'" "logger.error('Error:'"
|
|
1132
|
+
|
|
1133
|
+
# Remove debug statements
|
|
1134
|
+
sr --dry-run --verbose "src/**/*.js" "console.debug" "// console.debug"
|
|
1135
|
+
sr --dry-run --verbose "src/**/*.js" "console.log" "// console.log"
|
|
1136
|
+
|
|
1137
|
+
# Standardize imports
|
|
1138
|
+
sr --verbose "src/**/*.js" "import React from 'react';" "import React from 'react';"
|
|
1139
|
+
sr --verbose "src/**/*.js" "import { Component } from 'react';" "import { Component } from 'react';"
|
|
1140
|
+
|
|
1141
|
+
# Fix string formatting
|
|
1142
|
+
sr --verbose "src/**/*.js" "' + variable + '" "\`\${variable}\`"
|
|
1143
|
+
sr --verbose "src/**/*.js" '\" + variable + \"' "\`\${variable}\`"
|
|
1144
|
+
```
|
|
1145
|
+
|
|
1146
|
+
## Troubleshooting
|
|
1147
|
+
|
|
1148
|
+
### Common Issues and Solutions
|
|
1149
|
+
|
|
1150
|
+
#### Issue: "No files found matching pattern"
|
|
1151
|
+
|
|
1152
|
+
**Symptoms:**
|
|
1153
|
+
- Command completes quickly with "No files found" message
|
|
1154
|
+
- Exit code 2
|
|
1155
|
+
|
|
1156
|
+
**Solutions:**
|
|
1157
|
+
|
|
1158
|
+
```bash
|
|
1159
|
+
# 1. Check if pattern is quoted correctly
|
|
1160
|
+
# Wrong (shell expands pattern):
|
|
1161
|
+
sr *.txt "search" "replace"
|
|
1162
|
+
|
|
1163
|
+
# Correct (sr handles pattern):
|
|
1164
|
+
sr "*.txt" "search" "replace"
|
|
1165
|
+
|
|
1166
|
+
# 2. Check current directory
|
|
1167
|
+
pwd
|
|
1168
|
+
ls -la
|
|
1169
|
+
|
|
1170
|
+
# 3. Test pattern with find
|
|
1171
|
+
find . -name "*.txt" -type f | head -5
|
|
1172
|
+
|
|
1173
|
+
# 4. Use verbose mode for debugging
|
|
1174
|
+
sr -v "*.txt" "search" "replace"
|
|
1175
|
+
|
|
1176
|
+
# 5. Try explicit file list
|
|
1177
|
+
sr file1.txt file2.txt "search" "replace"
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
#### Issue: "Binary file detected, use --binary flag"
|
|
1181
|
+
|
|
1182
|
+
**Symptoms:**
|
|
1183
|
+
- Processing stops with binary file warning
|
|
1184
|
+
- Exit code 6
|
|
1185
|
+
|
|
1186
|
+
**Solutions:**
|
|
1187
|
+
|
|
1188
|
+
```bash
|
|
1189
|
+
# 1. Verify file type
|
|
1190
|
+
file suspicious-file.bin
|
|
1191
|
+
|
|
1192
|
+
# 2. Check if file is actually text
|
|
1193
|
+
head -c 100 suspicious-file.bin | cat -A
|
|
1194
|
+
|
|
1195
|
+
# 3. Use appropriate detection method
|
|
1196
|
+
sr --binary-method=file_only "*.bin" "search" "replace"
|
|
1197
|
+
|
|
1198
|
+
# 4. Skip binary files (if they shouldn't be processed)
|
|
1199
|
+
sr --exclude-patterns="*.bin,*.exe,*.dll" "*.txt" "search" "replace"
|
|
1200
|
+
|
|
1201
|
+
# 5. Process binary files explicitly (CAREFUL!)
|
|
1202
|
+
sr --binary "*.bin" "search" "replace"
|
|
1203
|
+
```
|
|
1204
|
+
|
|
1205
|
+
#### Issue: "Permission denied" on backup creation
|
|
1206
|
+
|
|
1207
|
+
**Symptoms:**
|
|
1208
|
+
- Operation fails with permission errors
|
|
1209
|
+
- Exit code 4 or 5
|
|
1210
|
+
|
|
1211
|
+
**Solutions:**
|
|
1212
|
+
|
|
1213
|
+
```bash
|
|
1214
|
+
# 1. Check current directory permissions
|
|
1215
|
+
ls -la .
|
|
1216
|
+
|
|
1217
|
+
# 2. Use different backup location
|
|
1218
|
+
sr -nbf "*.txt" "search" "replace"
|
|
1219
|
+
|
|
1220
|
+
# 3. Run with appropriate privileges
|
|
1221
|
+
sudo sr "*.txt" "search" "replace"
|
|
1222
|
+
|
|
1223
|
+
# 4. Change backup directory
|
|
1224
|
+
BACKUP_DIR="/tmp/sr-backups" sr "*.txt" "search" "replace"
|
|
1225
|
+
|
|
1226
|
+
# 5. Disable backups (last resort)
|
|
1227
|
+
sr -nb "*.txt" "search" "replace"
|
|
1228
|
+
```
|
|
1229
|
+
|
|
1230
|
+
#### Issue: Rollback not working as expected
|
|
1231
|
+
|
|
1232
|
+
**Symptoms:**
|
|
1233
|
+
- `--rollback` doesn't restore files
|
|
1234
|
+
- "No backup directories found" message
|
|
1235
|
+
|
|
1236
|
+
**Solutions:**
|
|
1237
|
+
|
|
1238
|
+
```bash
|
|
1239
|
+
# 1. List available backups
|
|
1240
|
+
sr --rollback-list
|
|
1241
|
+
|
|
1242
|
+
# 2. Check backup directory exists
|
|
1243
|
+
ls -la | grep sr.backup
|
|
1244
|
+
|
|
1245
|
+
# 3. Verify backup integrity
|
|
1246
|
+
ls -la sr.backup.*/.sr_session_metadata
|
|
1247
|
+
|
|
1248
|
+
# 4. Specify exact backup directory
|
|
1249
|
+
sr --rollback=sr.backup.20240115_143022_123456789
|
|
1250
|
+
|
|
1251
|
+
# 5. Check file permissions in backup
|
|
1252
|
+
ls -la sr.backup.*/* | head -10
|
|
1253
|
+
```
|
|
1254
|
+
|
|
1255
|
+
### Debug Mode Techniques
|
|
1256
|
+
|
|
1257
|
+
```bash
|
|
1258
|
+
# Enable comprehensive debugging
|
|
1259
|
+
sr -d "*.conf" "old" "new" 2>&1 | tee debug.log
|
|
1260
|
+
|
|
1261
|
+
# Debug specific components
|
|
1262
|
+
SR_DEBUG=true sr "*.txt" "search" "replace"
|
|
1263
|
+
|
|
1264
|
+
# Debug file discovery only
|
|
1265
|
+
sr -d --dry-run "*.js" "dummy" "dummy" 2>&1 | grep -i "found\|match"
|
|
1266
|
+
|
|
1267
|
+
# Debug binary detection
|
|
1268
|
+
sr -d --dry-run "*.bin" "dummy" "dummy" 2>&1 | grep -i "binary"
|
|
1269
|
+
|
|
1270
|
+
# Debug session management
|
|
1271
|
+
sr -d --dry-run "*.txt" "a" "b" 2>&1 | grep -i "session\|backup"
|
|
1272
|
+
```
|
|
1273
|
+
|
|
1274
|
+
### Diagnostic Commands
|
|
1275
|
+
|
|
1276
|
+
```bash
|
|
1277
|
+
# Check system compatibility
|
|
1278
|
+
for tool in bash find sed grep file stat; do
|
|
1279
|
+
if command -v $tool >/dev/null; then
|
|
1280
|
+
version=$($tool --version 2>&1 | head -1 | cut -d' ' -f2-4)
|
|
1281
|
+
echo "✓ $tool: $version"
|
|
1282
|
+
else
|
|
1283
|
+
echo "✗ $tool: NOT FOUND"
|
|
1284
|
+
fi
|
|
1285
|
+
done
|
|
1286
|
+
|
|
1287
|
+
# Test sr functionality
|
|
1288
|
+
test_sr() {
|
|
1289
|
+
echo "Testing sr functionality..."
|
|
1290
|
+
|
|
1291
|
+
# Create test files
|
|
1292
|
+
echo "test content old" > test1.txt
|
|
1293
|
+
echo "test content old" > test2.txt
|
|
1294
|
+
|
|
1295
|
+
# Test basic replacement
|
|
1296
|
+
sr --dry-run "*.txt" "old" "new"
|
|
1297
|
+
|
|
1298
|
+
# Test backup creation
|
|
1299
|
+
sr "*.txt" "old" "new"
|
|
1300
|
+
|
|
1301
|
+
# Test rollback
|
|
1302
|
+
sr --rollback
|
|
1303
|
+
|
|
1304
|
+
# Cleanup
|
|
1305
|
+
rm -f test1.txt test2.txt
|
|
1306
|
+
echo "Test completed"
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
# Run diagnostic
|
|
1310
|
+
test_sr
|
|
1311
|
+
```
|
|
1312
|
+
|
|
1313
|
+
### Performance Issues
|
|
1314
|
+
|
|
1315
|
+
**Symptoms:**
|
|
1316
|
+
- Slow processing of many small files
|
|
1317
|
+
- High memory usage with large files
|
|
1318
|
+
- Timeout on network filesystems
|
|
1319
|
+
|
|
1320
|
+
**Solutions:**
|
|
1321
|
+
|
|
1322
|
+
```bash
|
|
1323
|
+
# 1. Limit search depth
|
|
1324
|
+
sr -md 3 "*.js" "search" "replace"
|
|
1325
|
+
|
|
1326
|
+
# 2. Exclude large directories
|
|
1327
|
+
sr -xd node_modules,dist,vendor,target "*.js" "search" "replace"
|
|
1328
|
+
|
|
1329
|
+
# 3. Set file size limits
|
|
1330
|
+
sr -xs 10 "*.log" "search" "replace" # Max 10MB files
|
|
1331
|
+
|
|
1332
|
+
# 4. Use faster binary detection
|
|
1333
|
+
sr --binary-method=grep_only "*.txt" "search" "replace"
|
|
1334
|
+
|
|
1335
|
+
# 5. Process in batches
|
|
1336
|
+
find . -name "*.js" -type f | split -l 100 - batch-
|
|
1337
|
+
for batch in batch-*; do
|
|
1338
|
+
sr -- $(cat "$batch") "search" "replace"
|
|
1339
|
+
rm "$batch"
|
|
1340
|
+
done
|
|
1341
|
+
```
|
|
1342
|
+
|
|
1343
|
+
## Performance Optimization
|
|
1344
|
+
|
|
1345
|
+
### Benchmark Results
|
|
1346
|
+
|
|
1347
|
+
**Test Environment:** Ubuntu 20.04, SSD, 8-core CPU, 16GB RAM
|
|
1348
|
+
|
|
1349
|
+
| Scenario | Files | Total Size | Time | Rate |
|
|
1350
|
+
|----------|-------|------------|------|------|
|
|
1351
|
+
| Small text files | 1,000 | 10 MB | 2.1s | 476 files/s |
|
|
1352
|
+
| Mixed file types | 500 | 100 MB | 3.8s | 132 files/s |
|
|
1353
|
+
| Large files | 10 | 1 GB | 12.4s | 0.8 files/s |
|
|
1354
|
+
| Binary detection | 5,000 | 50 MB | 4.2s | 1,190 files/s |
|
|
1355
|
+
| Session rollback | 100 | 10 MB | 0.8s | 125 files/s |
|
|
1356
|
+
|
|
1357
|
+
### Optimization Techniques
|
|
1358
|
+
|
|
1359
|
+
#### File Discovery Optimization
|
|
1360
|
+
|
|
1361
|
+
```bash
|
|
1362
|
+
# Limit recursion depth
|
|
1363
|
+
sr -md 5 "*.conf" "search" "replace"
|
|
1364
|
+
|
|
1365
|
+
# Use specific patterns instead of wildcards
|
|
1366
|
+
sr "src/**/*.js" "search" "replace" # Better than "*.js"
|
|
1367
|
+
|
|
1368
|
+
# Exclude directories early
|
|
1369
|
+
sr -xd .git,node_modules,dist,build "*.js" "search" "replace"
|
|
1370
|
+
|
|
1371
|
+
# Use find-opts for complex filtering
|
|
1372
|
+
sr --find-opts="-type f -size -1M" "*.log" "search" "replace"
|
|
1373
|
+
```
|
|
1374
|
+
|
|
1375
|
+
#### Processing Optimization
|
|
1376
|
+
|
|
1377
|
+
```bash
|
|
1378
|
+
# Skip binary detection for known text files
|
|
1379
|
+
sr --binary-method=grep_only "*.txt" "search" "replace"
|
|
1380
|
+
|
|
1381
|
+
# Adjust binary check size
|
|
1382
|
+
sr --binary-check-size=512 "*.txt" "search" "replace"
|
|
1383
|
+
|
|
1384
|
+
# Disable unnecessary features
|
|
1385
|
+
sr -nb -xh "*.tmp" "search" "replace"
|
|
1386
|
+
|
|
1387
|
+
# Use appropriate replace mode
|
|
1388
|
+
sr --replace-mode=copy "*.txt" "search" "replace"
|
|
1389
|
+
```
|
|
1390
|
+
|
|
1391
|
+
#### Memory Optimization
|
|
1392
|
+
|
|
1393
|
+
```bash
|
|
1394
|
+
# Limit file size
|
|
1395
|
+
sr -xs 50 "*.log" "search" "replace" # Skip files > 50MB
|
|
1396
|
+
|
|
1397
|
+
# Process in batches
|
|
1398
|
+
find . -name "*.js" -type f -print0 | xargs -0 -n 100 sr -- "search" "replace"
|
|
1399
|
+
|
|
1400
|
+
# Use streaming for large files
|
|
1401
|
+
sr --sed-opts="-u" "largefile.txt" "search" "replace"
|
|
1402
|
+
```
|
|
1403
|
+
|
|
1404
|
+
### Parallel Processing
|
|
1405
|
+
|
|
1406
|
+
```bash
|
|
1407
|
+
#!/bin/bash
|
|
1408
|
+
# File: sr-parallel.sh
|
|
1409
|
+
# Parallel processing wrapper for large file sets
|
|
1410
|
+
|
|
1411
|
+
PATTERN="*.js"
|
|
1412
|
+
SEARCH="oldFunction"
|
|
1413
|
+
REPLACE="newFunction"
|
|
1414
|
+
THREADS=4
|
|
1415
|
+
|
|
1416
|
+
# Split file list
|
|
1417
|
+
find . -name "$PATTERN" -type f | split -n "l/$THREADS" - filelist-
|
|
1418
|
+
|
|
1419
|
+
# Process in parallel
|
|
1420
|
+
for list in filelist-*; do
|
|
1421
|
+
(
|
|
1422
|
+
echo "Processing $list"
|
|
1423
|
+
sr -- $(cat "$list") "$SEARCH" "$REPLACE"
|
|
1424
|
+
rm "$list"
|
|
1425
|
+
) &
|
|
1426
|
+
done
|
|
1427
|
+
|
|
1428
|
+
# Wait for all jobs
|
|
1429
|
+
wait
|
|
1430
|
+
echo "All parallel jobs completed"
|
|
1431
|
+
```
|
|
1432
|
+
|
|
1433
|
+
### Caching Strategies
|
|
1434
|
+
|
|
1435
|
+
```bash
|
|
1436
|
+
#!/bin/bash
|
|
1437
|
+
# File: sr-cached.sh
|
|
1438
|
+
# Cached file discovery for repeated operations
|
|
1439
|
+
|
|
1440
|
+
CACHE_DIR="/tmp/sr-cache"
|
|
1441
|
+
PATTERN="*.js"
|
|
1442
|
+
CACHE_FILE="$CACHE_DIR/$(echo "$PATTERN" | md5sum | cut -d' ' -f1).cache"
|
|
1443
|
+
|
|
1444
|
+
# Use cache if fresh (less than 1 hour old)
|
|
1445
|
+
if [[ -f "$CACHE_FILE" ]] && [[ $(find "$CACHE_FILE" -mmin -60) ]]; then
|
|
1446
|
+
echo "Using cached file list"
|
|
1447
|
+
FILES=$(cat "$CACHE_FILE")
|
|
1448
|
+
else
|
|
1449
|
+
echo "Building cache"
|
|
1450
|
+
mkdir -p "$CACHE_DIR"
|
|
1451
|
+
find . -name "$PATTERN" -type f > "$CACHE_FILE"
|
|
1452
|
+
FILES=$(cat "$CACHE_FILE")
|
|
1453
|
+
fi
|
|
1454
|
+
|
|
1455
|
+
# Process files
|
|
1456
|
+
sr -- $FILES "search" "replace"
|
|
1457
|
+
```
|
|
1458
|
+
|
|
1459
|
+
## Security Considerations
|
|
1460
|
+
|
|
1461
|
+
### Risk Assessment
|
|
1462
|
+
|
|
1463
|
+
| Risk Level | Scenario | Mitigation |
|
|
1464
|
+
|------------|----------|------------|
|
|
1465
|
+
| **Critical** | Processing binary files accidentally | Multi-layer detection, explicit `--binary` flag required |
|
|
1466
|
+
| **High** | Permission escalation via backup files | Preserve ownership, validate file paths |
|
|
1467
|
+
| **Medium** | Resource exhaustion with large files | File size limits, depth limits |
|
|
1468
|
+
| **Low** | Information disclosure in metadata | Session metadata contains only command info |
|
|
1469
|
+
|
|
1470
|
+
### Security Best Practices
|
|
1471
|
+
|
|
1472
|
+
#### 1. Access Control
|
|
1473
|
+
|
|
1474
|
+
```bash
|
|
1475
|
+
# Run with least privileges
|
|
1476
|
+
sudo -u appuser sr "*.conf" "search" "replace"
|
|
1477
|
+
|
|
1478
|
+
# Use dedicated service account
|
|
1479
|
+
useradd -r -s /bin/false sr-user
|
|
1480
|
+
sudo -u sr-user sr "*.conf" "search" "replace"
|
|
1481
|
+
|
|
1482
|
+
# Restrict backup directory access
|
|
1483
|
+
mkdir -p /var/backups/sr
|
|
1484
|
+
chmod 700 /var/backups/sr
|
|
1485
|
+
chown root:root /var/backups/sr
|
|
1486
|
+
```
|
|
1487
|
+
|
|
1488
|
+
#### 2. Input Validation
|
|
1489
|
+
|
|
1490
|
+
```bash
|
|
1491
|
+
# Validate patterns before processing
|
|
1492
|
+
validate_pattern() {
|
|
1493
|
+
local pattern="$1"
|
|
1494
|
+
|
|
1495
|
+
# Reject patterns with directory traversal
|
|
1496
|
+
if [[ "$pattern" == *".."* ]] || [[ "$pattern" == *"/"* ]]; then
|
|
1497
|
+
echo "Error: Pattern may contain directory traversal"
|
|
1498
|
+
return 1
|
|
1499
|
+
fi
|
|
1500
|
+
|
|
1501
|
+
# Limit pattern complexity
|
|
1502
|
+
if [[ "$pattern" == *"**"* ]] && [[ "$pattern" != "**"* ]]; then
|
|
1503
|
+
echo "Error: Complex glob patterns not allowed"
|
|
1504
|
+
return 1
|
|
1505
|
+
fi
|
|
1506
|
+
|
|
1507
|
+
return 0
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
# Safe wrapper
|
|
1511
|
+
sr_safe() {
|
|
1512
|
+
validate_pattern "$1" || return 1
|
|
1513
|
+
sr "$@"
|
|
1514
|
+
}
|
|
1515
|
+
```
|
|
1516
|
+
|
|
1517
|
+
#### 3. Audit Logging
|
|
1518
|
+
|
|
1519
|
+
```bash
|
|
1520
|
+
#!/bin/bash
|
|
1521
|
+
# File: sr-audit.sh
|
|
1522
|
+
# Comprehensive audit logging wrapper
|
|
1523
|
+
|
|
1524
|
+
AUDIT_LOG="/var/log/sr-audit.log"
|
|
1525
|
+
SESSION_LOG="/var/log/sr-sessions.log"
|
|
1526
|
+
|
|
1527
|
+
# Log all invocations
|
|
1528
|
+
log_invocation() {
|
|
1529
|
+
local user=$(whoami)
|
|
1530
|
+
local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
1531
|
+
local session="${SESSION_ID:-pre-init}"
|
|
1532
|
+
|
|
1533
|
+
echo "$timestamp | INVOKE | user=$user | session=$session | args=$*" >> "$AUDIT_LOG"
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
# Log session creation
|
|
1537
|
+
log_session() {
|
|
1538
|
+
local session="$1"
|
|
1539
|
+
local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
1540
|
+
|
|
1541
|
+
echo "$timestamp | SESSION | id=$session | args=${*:2}" >> "$SESSION_LOG"
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
# Main execution
|
|
1545
|
+
log_invocation "$@"
|
|
1546
|
+
|
|
1547
|
+
# Capture session ID
|
|
1548
|
+
SESSION_FILE=$(mktemp)
|
|
1549
|
+
sr "$@" 2>&1 | tee "$SESSION_FILE"
|
|
1550
|
+
EXIT_CODE=$?
|
|
1551
|
+
|
|
1552
|
+
# Extract session ID
|
|
1553
|
+
SESSION_ID=$(grep "Session ID:" "$SESSION_FILE" | cut -d: -f2 | xargs)
|
|
1554
|
+
if [[ -n "$SESSION_ID" ]]; then
|
|
1555
|
+
log_session "$SESSION_ID" "$@"
|
|
1556
|
+
fi
|
|
1557
|
+
|
|
1558
|
+
rm "$SESSION_FILE"
|
|
1559
|
+
exit $EXIT_CODE
|
|
1560
|
+
```
|
|
1561
|
+
|
|
1562
|
+
#### 4. Network Security
|
|
1563
|
+
|
|
1564
|
+
```bash
|
|
1565
|
+
# Disable network operations in secure environments
|
|
1566
|
+
export SR_NO_NETWORK=true
|
|
1567
|
+
|
|
1568
|
+
# Validate URLs in replacements
|
|
1569
|
+
validate_url() {
|
|
1570
|
+
local url="$1"
|
|
1571
|
+
|
|
1572
|
+
# Allow only specific domains in production
|
|
1573
|
+
if [[ "$ENVIRONMENT" == "prod" ]]; then
|
|
1574
|
+
if [[ ! "$url" =~ ^https://(api\.example\.com|cdn\.example\.com) ]]; then
|
|
1575
|
+
echo "Error: URL not allowed in production: $url"
|
|
1576
|
+
return 1
|
|
1577
|
+
fi
|
|
1578
|
+
fi
|
|
1579
|
+
|
|
1580
|
+
return 0
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
# Safe replacement wrapper
|
|
1584
|
+
sr_replace_safe() {
|
|
1585
|
+
validate_url "$3" || return 1
|
|
1586
|
+
sr "$1" "$2" "$3"
|
|
1587
|
+
}
|
|
1588
|
+
```
|
|
1589
|
+
|
|
1590
|
+
### Compliance Considerations
|
|
1591
|
+
|
|
1592
|
+
#### GDPR Compliance
|
|
1593
|
+
|
|
1594
|
+
```bash
|
|
1595
|
+
# PII detection and redaction
|
|
1596
|
+
sr --dry-run -E "*.log" \
|
|
1597
|
+
"([0-9]{3}-[0-9]{2}-[0-9]{4})" \
|
|
1598
|
+
"[SSN REDACTED]"
|
|
1599
|
+
|
|
1600
|
+
# Email address redaction
|
|
1601
|
+
sr --dry-run -E "*.txt" \
|
|
1602
|
+
"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})" \
|
|
1603
|
+
"[EMAIL REDACTED]"
|
|
1604
|
+
|
|
1605
|
+
# Credit card redaction
|
|
1606
|
+
sr --dry-run -E "*.db" \
|
|
1607
|
+
"([0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4})" \
|
|
1608
|
+
"[CC REDACTED]"
|
|
1609
|
+
```
|
|
1610
|
+
|
|
1611
|
+
#### HIPAA Compliance
|
|
1612
|
+
|
|
1613
|
+
```bash
|
|
1614
|
+
# PHI detection patterns
|
|
1615
|
+
PHI_PATTERNS=(
|
|
1616
|
+
"patient name"
|
|
1617
|
+
"medical record"
|
|
1618
|
+
"diagnosis code"
|
|
1619
|
+
"treatment plan"
|
|
1620
|
+
)
|
|
1621
|
+
|
|
1622
|
+
for pattern in "${PHI_PATTERNS[@]}"; do
|
|
1623
|
+
sr --dry-run -i "*.doc" "$pattern" "[PHI REDACTED]"
|
|
1624
|
+
done
|
|
1625
|
+
```
|
|
1626
|
+
|
|
1627
|
+
#### PCI DSS Compliance
|
|
1628
|
+
|
|
1629
|
+
```bash
|
|
1630
|
+
# Cardholder data detection
|
|
1631
|
+
sr --dry-run -E "*.csv" \
|
|
1632
|
+
"\b(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14})\b" \
|
|
1633
|
+
"[PAN REDACTED]"
|
|
1634
|
+
|
|
1635
|
+
# Track data detection
|
|
1636
|
+
sr --dry-run -E "*.log" \
|
|
1637
|
+
"%B[0-9]{16}\^" \
|
|
1638
|
+
"[TRACK DATA REDACTED]"
|
|
1639
|
+
```
|
|
1640
|
+
|
|
1641
|
+
## Version History
|
|
1642
|
+
|
|
1643
|
+
### Version 6.1.0 (Current) - January 2025
|
|
1644
|
+
|
|
1645
|
+
**Major Enhancements:**
|
|
1646
|
+
- Enhanced configuration system with tool-specific parameter passing
|
|
1647
|
+
- Extended search options: case-insensitive, word boundaries, extended regex
|
|
1648
|
+
- Direct flag passing to find/sed/grep via `--find-opts`, `--sed-opts`, `--grep-opts`
|
|
1649
|
+
- Improved compatibility with GNU/BSD sed variations
|
|
1650
|
+
- Configurable base tool commands and default flags
|
|
1651
|
+
- Enhanced documentation with complete tool flag reference
|
|
1652
|
+
|
|
1653
|
+
**New Features:**
|
|
1654
|
+
- Tool configuration variables in script header
|
|
1655
|
+
- Extended regex support with `-E, --extended-regex`
|
|
1656
|
+
- Case-insensitive matching with `-i, --ignore-case`
|
|
1657
|
+
- Word boundary matching with `-w, --word-boundary`
|
|
1658
|
+
- Multi-line mode support with `-m, --multiline`
|
|
1659
|
+
- Line number display with `-n, --line-numbers`
|
|
1660
|
+
- Dot matches newline with `--dot-all`
|
|
1661
|
+
- Global replace control with `--no-global`
|
|
1662
|
+
|
|
1663
|
+
**Improvements:**
|
|
1664
|
+
- Performance optimization for large file sets
|
|
1665
|
+
- Better handling of special characters and escape sequences
|
|
1666
|
+
- Improved binary file detection accuracy
|
|
1667
|
+
- Enhanced error messages and debugging information
|
|
1668
|
+
- More robust session tracking and metadata management
|
|
1669
|
+
|
|
1670
|
+
### Version 6.0.0 - December 2025
|
|
1671
|
+
|
|
1672
|
+
**Major Features:**
|
|
1673
|
+
- Session-based rollback with complete metadata tracking
|
|
1674
|
+
- Multi-layer binary file detection system
|
|
1675
|
+
- Session ID generation with nanosecond precision
|
|
1676
|
+
- Enhanced backup metadata storage
|
|
1677
|
+
- Comprehensive rollback debugging system
|
|
1678
|
+
|
|
1679
|
+
**Key Improvements:**
|
|
1680
|
+
- Robust error handling with detailed error messages
|
|
1681
|
+
- Performance optimization for large file sets
|
|
1682
|
+
- Better handling of special characters and escape sequences
|
|
1683
|
+
- Improved binary file detection accuracy
|
|
1684
|
+
|
|
1685
|
+
### Version 5.0.0 - October 2024
|
|
1686
|
+
|
|
1687
|
+
**Major Features:**
|
|
1688
|
+
- Predictable argument parsing system
|
|
1689
|
+
- Multi-platform compatibility (Linux, macOS, BSD)
|
|
1690
|
+
- Configurable safety limits and exclusions
|
|
1691
|
+
- Comprehensive logging system
|
|
1692
|
+
- Dry-run mode for testing
|
|
1693
|
+
|
|
1694
|
+
### Version 4.0.0 - August 2023
|
|
1695
|
+
|
|
1696
|
+
**Major Features:**
|
|
1697
|
+
- Recursive directory traversal
|
|
1698
|
+
- Binary file detection and exclusion
|
|
1699
|
+
- Backup creation system
|
|
1700
|
+
- File ownership preservation
|
|
1701
|
+
- Exclusion patterns and directories
|
|
1702
|
+
|
|
1703
|
+
### Version 3.0.0 - June 2023
|
|
1704
|
+
|
|
1705
|
+
**Major Features:**
|
|
1706
|
+
- Basic search and replace functionality
|
|
1707
|
+
- Simple backup system
|
|
1708
|
+
- Error handling framework
|
|
1709
|
+
- Basic logging
|
|
1710
|
+
|
|
1711
|
+
### Version 2.0.0 - April 2023
|
|
1712
|
+
|
|
1713
|
+
**Major Features:**
|
|
1714
|
+
- Initial release with core functionality
|
|
1715
|
+
- File pattern matching
|
|
1716
|
+
- Basic text replacement
|
|
1717
|
+
- Minimal safety features
|
|
1718
|
+
|
|
1719
|
+
### Version 1.0.0 - January 2023
|
|
1720
|
+
|
|
1721
|
+
**Initial Release:**
|
|
1722
|
+
- Proof of concept implementation
|
|
1723
|
+
- Basic command-line interface
|
|
1724
|
+
- Simple file processing
|
|
1725
|
+
|
|
1726
|
+
## Contributing
|
|
1727
|
+
|
|
1728
|
+
We welcome contributions from the community! Here's how you can help:
|
|
1729
|
+
|
|
1730
|
+
### Development Workflow
|
|
1731
|
+
|
|
1732
|
+
1. **Fork the Repository**
|
|
1733
|
+
```bash
|
|
1734
|
+
git clone https://github.com/paulmann/sr-search-replace.git
|
|
1735
|
+
cd sr-search-replace
|
|
1736
|
+
git checkout -b feature/your-feature-name
|
|
1737
|
+
```
|
|
1738
|
+
|
|
1739
|
+
2. **Make Changes**
|
|
1740
|
+
```bash
|
|
1741
|
+
# Test your changes thoroughly
|
|
1742
|
+
./sr.sh --dry-run -v "*.txt" "test" "TEST"
|
|
1743
|
+
|
|
1744
|
+
# Run all tests
|
|
1745
|
+
./test-runner.sh
|
|
1746
|
+
|
|
1747
|
+
# Check for shell script issues
|
|
1748
|
+
shellcheck sr.sh
|
|
1749
|
+
```
|
|
1750
|
+
|
|
1751
|
+
3. **Submit Pull Request**
|
|
1752
|
+
- Ensure code follows existing style conventions
|
|
1753
|
+
- Add comments for complex logic
|
|
1754
|
+
- Update documentation if adding features
|
|
1755
|
+
- Test with various Bash versions (4.0+)
|
|
1756
|
+
|
|
1757
|
+
### Coding Standards
|
|
1758
|
+
|
|
1759
|
+
```bash
|
|
1760
|
+
#!/bin/bash
|
|
1761
|
+
# Example of coding standards:
|
|
1762
|
+
|
|
1763
|
+
# 1. Use readonly for constants
|
|
1764
|
+
readonly DEFAULT_MAX_DEPTH=100
|
|
1765
|
+
|
|
1766
|
+
# 2. Use declare -g for global variables
|
|
1767
|
+
declare -g PROCESSED_FILES=0
|
|
1768
|
+
|
|
1769
|
+
# 3. Use local for function variables
|
|
1770
|
+
function example() {
|
|
1771
|
+
local local_var="value"
|
|
1772
|
+
# ...
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
# 4. Use meaningful variable names
|
|
1776
|
+
declare -gi TOTAL_REPLACEMENTS=0 # 'i' for integer
|
|
1777
|
+
|
|
1778
|
+
# 5. Document complex functions
|
|
1779
|
+
# Function: perform_replace
|
|
1780
|
+
# Description: Perform search and replace on a single file
|
|
1781
|
+
# Parameters:
|
|
1782
|
+
# $1: File path
|
|
1783
|
+
# $2: Search string (escaped)
|
|
1784
|
+
# $3: Replace string (escaped)
|
|
1785
|
+
# $4: Timestamp
|
|
1786
|
+
# Returns: 0 on success, error code on failure
|
|
1787
|
+
perform_replace() {
|
|
1788
|
+
# Function implementation
|
|
1789
|
+
}
|
|
1790
|
+
```
|
|
1791
|
+
|
|
1792
|
+
### Testing Guidelines
|
|
1793
|
+
|
|
1794
|
+
```bash
|
|
1795
|
+
# Run comprehensive test suite
|
|
1796
|
+
./run-tests.sh
|
|
1797
|
+
|
|
1798
|
+
# Test specific functionality
|
|
1799
|
+
test_binary_detection() {
|
|
1800
|
+
# Test cases for binary detection
|
|
1801
|
+
# ...
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
test_rollback_system() {
|
|
1805
|
+
# Test cases for rollback
|
|
1806
|
+
# ...
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
test_performance() {
|
|
1810
|
+
# Performance benchmarks
|
|
1811
|
+
# ...
|
|
1812
|
+
}
|
|
1813
|
+
```
|
|
1814
|
+
|
|
1815
|
+
### Documentation Updates
|
|
1816
|
+
|
|
1817
|
+
When adding new features:
|
|
1818
|
+
|
|
1819
|
+
1. Update README.md with new functionality
|
|
1820
|
+
2. Add examples for new options
|
|
1821
|
+
3. Update version history
|
|
1822
|
+
4. Consider adding tutorial or guide if feature is complex
|
|
1823
|
+
5. Update command-line help (`show_help` function)
|
|
1824
|
+
|
|
1825
|
+
## License
|
|
1826
|
+
|
|
1827
|
+
MIT License
|
|
1828
|
+
|
|
1829
|
+
Copyright (c) 2023-2025 Mikhail Deynekin
|
|
1830
|
+
|
|
1831
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1832
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
1833
|
+
in the Software without restriction, including without limitation the rights
|
|
1834
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1835
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
1836
|
+
furnished to do so, subject to the following conditions:
|
|
1837
|
+
|
|
1838
|
+
The above copyright notice and this permission notice shall be included in all
|
|
1839
|
+
copies or substantial portions of the Software.
|
|
1840
|
+
|
|
1841
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1842
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1843
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1844
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1845
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1846
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1847
|
+
SOFTWARE.
|
|
1848
|
+
|
|
1849
|
+
## Support
|
|
1850
|
+
|
|
1851
|
+
### Documentation Resources
|
|
1852
|
+
|
|
1853
|
+
- 📖 [Wiki Documentation](https://github.com/paulmann/sr-search-replace/wiki) - Complete user guide
|
|
1854
|
+
- 📘 [Command Reference](https://github.com/paulmann/sr-search-replace/wiki/Command-Reference) - Detailed option reference
|
|
1855
|
+
- 🚀 [Quick Start Tutorial](https://github.com/paulmann/sr-search-replace/wiki/Quick-Start-Tutorial) - Step-by-step guide
|
|
1856
|
+
- 📚 [Installation Guide](https://github.com/paulmann/sr-search-replace/wiki/Installation-Guide) - Multi-platform installation
|
|
1857
|
+
- 💡 [Basic Examples](https://github.com/paulmann/sr-search-replace/wiki/Basic-Examples) - Common use cases
|
|
1858
|
+
|
|
1859
|
+
|
|
1860
|
+
### Community Support
|
|
1861
|
+
|
|
1862
|
+
- **🐛 [Issue Tracker](https://github.com/paulmann/sr-search-replace/issues)** - Report bugs or request features
|
|
1863
|
+
- **💬 [Discussions](https://github.com/paulmann/sr-search-replace/discussions)** - Ask questions and share ideas
|
|
1864
|
+
- **📧 [Email Support](mailto:mid1977@gmail.com)** - Direct support for critical issues
|
|
1865
|
+
- **🔧 [Professional Support](https://deynekin.com/consulting)** - Commercial support and consulting
|
|
1866
|
+
|
|
1867
|
+
### Contributing to Support
|
|
1868
|
+
|
|
1869
|
+
- **🌍 [Community Discussions](https://github.com/paulmann/sr-search-replace/discussions)** - Help translate and share knowledge
|
|
1870
|
+
- **✍️ [Contributing Guide](https://github.com/paulmann/sr-search-replace/wiki/Contributing-Guide)** - How to contribute code
|
|
1871
|
+
- **🐛 [Troubleshooting](https://github.com/paulmann/sr-search-replace/wiki/Troubleshooting)** - Common issues and solutions
|
|
1872
|
+
- **🔍 [Code Review](https://github.com/paulmann/sr-search-replace/pulls)** - Review pull requests
|
|
1873
|
+
|
|
1874
|
+
|
|
1875
|
+
## FAQ
|
|
1876
|
+
|
|
1877
|
+
### Frequently Asked Questions
|
|
1878
|
+
|
|
1879
|
+
#### Q: Why use `sr` instead of `sed -i` or `perl -pi -e`?
|
|
1880
|
+
**A:** `sr` provides comprehensive safety features that basic tools lack:
|
|
1881
|
+
- Automatic backups before modification
|
|
1882
|
+
- Binary file detection to prevent corruption
|
|
1883
|
+
- Session tracking for reliable rollback
|
|
1884
|
+
- Configurable safety limits and exclusions
|
|
1885
|
+
- Detailed logging and audit trails
|
|
1886
|
+
|
|
1887
|
+
#### Q: Is `sr` safe to use on production systems?
|
|
1888
|
+
**A:** Yes, with proper precautions:
|
|
1889
|
+
- Always use `--dry-run` first to preview changes
|
|
1890
|
+
- Set appropriate safety limits (`-md`, `-xs`)
|
|
1891
|
+
- Enable backups (default behavior)
|
|
1892
|
+
- Test in staging environment first
|
|
1893
|
+
- Use session tracking for easy rollback
|
|
1894
|
+
|
|
1895
|
+
#### Q: How does `sr` handle very large files?
|
|
1896
|
+
**A:** `sr` includes several protections:
|
|
1897
|
+
- Configurable file size limits (`-xs` option)
|
|
1898
|
+
- Streaming processing for large files
|
|
1899
|
+
- Memory-efficient operations
|
|
1900
|
+
- Optional chunked processing for huge files
|
|
1901
|
+
|
|
1902
|
+
#### Q: Can `sr` process binary files?
|
|
1903
|
+
**A:** Yes, but only with explicit permission:
|
|
1904
|
+
- Binary files are detected and skipped by default
|
|
1905
|
+
- Use `--binary` flag to allow processing
|
|
1906
|
+
- Multi-layer detection ensures accurate identification
|
|
1907
|
+
- Always test with `--dry-run` first
|
|
1908
|
+
|
|
1909
|
+
#### Q: How does the rollback system work?
|
|
1910
|
+
**A:** The rollback system provides:
|
|
1911
|
+
- Automatic session tracking for each operation
|
|
1912
|
+
- Complete backup of modified files
|
|
1913
|
+
- Metadata including command, timestamp, and user
|
|
1914
|
+
- One-command restoration with `--rollback`
|
|
1915
|
+
- Interactive confirmation with timeout
|
|
1916
|
+
|
|
1917
|
+
#### Q: Is `sr` compatible with my operating system?
|
|
1918
|
+
**A:** `sr` is compatible with:
|
|
1919
|
+
- Linux (all major distributions)
|
|
1920
|
+
- macOS (10.15+ with GNU coreutils)
|
|
1921
|
+
- BSD systems (with some limitations)
|
|
1922
|
+
- Windows WSL/WSL2 (fully compatible)
|
|
1923
|
+
|
|
1924
|
+
#### Q: How can I extend `sr` for my specific needs?
|
|
1925
|
+
**A:** Several extension mechanisms are available:
|
|
1926
|
+
- Environment variables for configuration
|
|
1927
|
+
- Wrapper scripts for custom behavior
|
|
1928
|
+
- Tool-specific parameter passing (`--find-opts`, etc.)
|
|
1929
|
+
- Source modification (open source MIT license)
|
|
1930
|
+
|
|
1931
|
+
#### Q: What's the performance impact of using `sr`?
|
|
1932
|
+
**A:** Minimal overhead with significant benefits:
|
|
1933
|
+
- File discovery: ~1000 files/second
|
|
1934
|
+
- Binary detection: ~10,000 files/second
|
|
1935
|
+
- Replacement: 50-500 replacements/second
|
|
1936
|
+
- Backup creation: ~100 files/second
|
|
1937
|
+
- Rollback: ~200 files/second
|
|
1938
|
+
|
|
1939
|
+
#### Q: How do I contribute to `sr` development?
|
|
1940
|
+
**A:** Contributions are welcome:
|
|
1941
|
+
- Fork the repository on GitHub
|
|
1942
|
+
- Follow coding standards and conventions
|
|
1943
|
+
- Add tests for new functionality
|
|
1944
|
+
- Update documentation
|
|
1945
|
+
- Submit pull requests
|
|
1946
|
+
|
|
1947
|
+
---
|
|
1948
|
+
|
|
1949
|
+
**Made with ❤️ for developers and system administrators**
|
|
1950
|
+
|
|
1951
|
+
*Search & Replace (sr) - Because your data is too important for simple text manipulation.*
|