本文目录导读:

我来为您编写一个限定目录范围的代码替换脚本,提供几种常见实现方式:
Python版本(最灵活)
#!/usr/bin/env python3
"""
限定目录范围的代码替换脚本
功能:在指定目录范围内查找并替换文本
"""
import os
import re
import argparse
from pathlib import Path
class DirectoryLimitedReplacer:
def __init__(self, base_dir, include_extensions=None, exclude_dirs=None):
"""
初始化替换器
Args:
base_dir: 基础目录
include_extensions: 要处理的文件扩展名列表,如 ['.py', '.js']
exclude_dirs: 要排除的目录名列表
"""
self.base_dir = Path(base_dir)
self.include_extensions = include_extensions or ['.py', '.js', '.html', '.css']
self.exclude_dirs = exclude_dirs or ['.git', '__pycache__', 'node_modules', 'venv']
self.changed_files = []
def should_process_file(self, file_path):
"""判断是否应该处理该文件"""
# 检查扩展名
if file_path.suffix not in self.include_extensions:
return False
# 检查是否在排除目录中
for part in file_path.parts:
if part in self.exclude_dirs:
return False
return True
def replace_in_file(self, file_path, old_text, new_text, use_regex=False):
"""在单个文件中执行替换"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
if use_regex:
new_content = re.sub(old_text, new_text, content)
else:
new_content = content.replace(old_text, new_text)
if new_content != content:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(new_content)
self.changed_files.append(str(file_path))
return True
return False
except Exception as e:
print(f"Error processing {file_path}: {e}")
return False
def replace_all(self, old_text, new_text, use_regex=False):
"""在范围内所有文件中执行替换"""
for file_path in self.base_dir.rglob('*'):
if file_path.is_file() and self.should_process_file(file_path):
self.replace_in_file(file_path, old_text, new_text, use_regex)
return self.changed_files
def main():
parser = argparse.ArgumentParser(description='限定目录范围的代码替换工具')
parser.add_argument('old_text', help='要替换的文本')
parser.add_argument('new_text', help='替换后的文本')
parser.add_argument('--dir', '-d', default='.', help='目标目录(默认为当前目录)')
parser.add_argument('--extensions', '-e', nargs='+',
default=['.py', '.js', '.html', '.css', '.txt'],
help='要处理的文件扩展名')
parser.add_argument('--exclude', '-x', nargs='+',
default=['.git', '__pycache__', 'node_modules'],
help='要排除的目录')
parser.add_argument('--regex', '-r', action='store_true',
help='使用正则表达式匹配')
parser.add_argument('--dry-run', action='store_true',
help='仅显示将要修改的文件,不实际修改')
args = parser.parse_args()
replacer = DirectoryLimitedReplacer(
args.dir,
include_extensions=args.extensions,
exclude_dirs=args.exclude
)
if args.dry_run:
print("【模拟运行模式】将修改以下文件:")
for file_path in Path(args.dir).rglob('*'):
if file_path.is_file() and replacer.should_process_file(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
if args.regex:
if re.search(args.old_text, content):
print(f" {file_path}")
else:
if args.old_text in content:
print(f" {file_path}")
else:
changed = replacer.replace_all(args.old_text, args.new_text, args.regex)
print(f"修改完成,共修改 {len(changed)} 个文件:")
for f in changed:
print(f" {f}")
if __name__ == '__main__':
main()
Shell脚本版本(Linux/Mac)
#!/bin/bash
# filename: limited_replace.sh
# 限定目录范围的代码替换脚本
# 使用方式: ./limited_replace.sh "旧文本" "新文本" [目录] [扩展名]
OLD_TEXT="${1}"
NEW_TEXT="${2}"
TARGET_DIR="${3:-.}"
EXTENSIONS="${4:-py,js,html,css,txt}"
# 排除的目录
EXCLUDE_DIRS=(".git" "__pycache__" "node_modules" "venv")
# 颜色
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
echo "开始替换操作..."
echo "目标目录: $TARGET_DIR"
echo "替换文本: '$OLD_TEXT' -> '$NEW_TEXT'"
echo "文件类型: $EXTENSIONS"
# 构建find命令的排除参数
EXCLUDE_ARGS=""
for dir in "${EXCLUDE_DIRS[@]}"; do
EXCLUDE_ARGS="$EXCLUDE_ARGS -not -path '*/$dir/*'"
done
# 将扩展名转换为find格式
IFS=',' read -ra EXT_ARRAY <<< "$EXTENSIONS"
FIND_EXT_ARGS=""
for ext in "${EXT_ARRAY[@]}"; do
if [ -z "$FIND_EXT_ARGS" ]; then
FIND_EXT_ARGS="-name '*.$ext'"
else
FIND_EXT_ARGS="$FIND_EXT_ARGS -o -name '*.$ext'"
fi
done
# 查找并替换
find "$TARGET_DIR" -type f $FIND_EXT_ARGS $EXCLUDE_ARGS | while read -r file; do
if grep -q "$OLD_TEXT" "$file" 2>/dev/null; then
echo -e "${GREEN}修改:${NC} $file"
# MacOS使用sed -i '',Linux使用sed -i
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' "s|$OLD_TEXT|$NEW_TEXT|g" "$file"
else
sed -i "s|$OLD_TEXT|$NEW_TEXT|g" "$file"
fi
fi
done
echo -e "${GREEN}替换完成!${NC}"
PowerShell版本(Windows)
# filename: LimitedReplace.ps1
# 限定目录范围的代码替换脚本
param(
[Parameter(Mandatory=$true)]
[string]$OldText,
[Parameter(Mandatory=$true)]
[string]$NewText,
[string]$TargetDir = ".",
[string[]]$Extensions = @("*.py", "*.js", "*.html", "*.css", "*.txt"),
[string[]]$ExcludeDirs = @(".git", "__pycache__", "node_modules", "venv"),
[switch]$DryRun,
[switch]$UseRegex
)
# 获取所有符合条件的文件
Write-Host "正在扫描文件..." -ForegroundColor Cyan
$files = Get-ChildItem -Path $TargetDir -Recurse -File -Include $Extensions |
Where-Object {
$exclude = $false
foreach ($dir in $ExcludeDirs) {
if ($_.FullName -match [regex]::Escape($dir)) {
$exclude = $true
break
}
}
-not $exclude
}
$changedFiles = @()
foreach ($file in $files) {
try {
$content = Get-Content -Path $file.FullName -Raw
if ($UseRegex) {
$newContent = $content -replace $OldText, $NewText
} else {
$newContent = $content -replace [regex]::Escape($OldText), $NewText
}
if ($newContent -ne $content) {
if (-not $DryRun) {
Set-Content -Path $file.FullName -Value $newContent -NoNewline
}
$changedFiles += $file.FullName
Write-Host "$(if ($DryRun) {'[模拟]'} else {'[修改]'}) $($file.FullName)" -ForegroundColor Green
}
}
catch {
Write-Warning "处理文件 $($file.FullName) 时出错: $_"
}
}
Write-Host "`n操作完成!" -ForegroundColor Cyan
Write-Host "共处理文件: $($files.Count) 个"
Write-Host "实际修改: $($changedFiles.Count) 个"
if ($changedFiles.Count -gt 0) {
Write-Host "`n修改的文件列表:" -ForegroundColor Yellow
$changedFiles | ForEach-Object { Write-Host " $_" }
}
使用示例
Python版本
# 基本使用 python replace_script.py "旧代码" "新代码" # 指定目录和文件类型 python replace_script.py "console.log" "logger.info" -d ./src -e .js .ts # 使用正则表达式 python replace_script.py "var\s+(\w+)" "let $1" -r # 模拟运行(不实际修改) python replace_script.py "旧文本" "新文本" --dry-run
Shell版本
# 添加执行权限 chmod +x limited_replace.sh # 在当前目录替换 ./limited_replace.sh "old_text" "new_text" # 在指定目录替换JS文件 ./limited_replace.sh "var " "let " ./src js # 使用不同的分隔符避免冲突 ./limited_replace.sh "path/to/old" "path/to/new" ./config
PowerShell版本
# 设置执行策略(如果需要)
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
# 基本使用
.\LimitedReplace.ps1 -OldText "旧代码" -NewText "新代码"
# 高级使用
.\LimitedReplace.ps1 -OldText "function\(" -NewText "async function(" `
-TargetDir ./src -Extensions *.js,*.ts `
-ExcludeDirs node_modules,dist -UseRegex
# 模拟运行
.\LimitedReplace.ps1 -OldText "旧文本" -NewText "新文本" -DryRun
安全建议
- 始终先备份:在执行替换前备份重要文件
- 使用模拟模式:先用
--dry-run或-WhatIf查看将要修改的文件 - 限制搜索范围:精确指定目录和文件类型,避免意外修改
- 使用版本控制:在Git仓库中使用前,确保工作区干净
- 测试正则表达式:使用
-r正则模式时,先用小范围测试
选择哪个版本取决于您的操作系统和使用场景:
- Python版本:跨平台,功能最完整
- Shell版本:Linux/Mac环境最方便
- PowerShell版本:Windows环境原生支持