本文目录导读:

我来介绍几种在Shell脚本中批量替换文件内容的方法:
使用 sed 命令(最常用)
基本语法
sed -i 's/原字符串/新字符串/g' 文件名
批量替换示例
#!/bin/bash
# 批量替换当前目录下所有 .txt 文件
sed -i 's/old_text/new_text/g' *.txt
# 替换指定目录下的所有文件
sed -i 's/old_text/new_text/g' /path/to/directory/*.txt
# 递归替换子目录中的文件
find /path/to/directory -type f -name "*.txt" -exec sed -i 's/old_text/new_text/g' {} \;
更复杂的 sed 示例
#!/bin/bash
# 1. 替换多个字符串
sed -i -e 's/old_text1/new_text1/g' -e 's/old_text2/new_text2/g' file.txt
# 2. 正则表达式替换
sed -i 's/[0-9]\{4\}/2024/g' file.txt # 替换4位数字为2024
# 3. 备份原文件(创建.bak备份)
sed -i.bak 's/old/new/g' file.txt
使用 find + sed 组合(推荐)
#!/bin/bash
# 递归替换 .php 和 .html 文件
find . -type f \( -name "*.php" -o -name "*.html" \) -exec sed -i 's/旧内容/新内容/g' {} \;
# 排除特定目录
find . -type f -name "*.txt" ! -path "./backup/*" -exec sed -i 's/old/new/g' {} \;
# 仅替换包含特定字符串的文件
grep -rl "old_text" . --include="*.txt" | xargs sed -i 's/old_text/new_text/g'
使用 awk 命令
#!/bin/bash
# 使用 awk 替换
awk '{gsub(/old_text/, "new_text"); print}' file.txt > temp.txt && mv temp.txt file.txt
# 批量处理
for file in *.txt; do
awk '{gsub(/old_text/, "new_text"); print}' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file"
done
完整的批量替换脚本示例
#!/bin/bash
# batch_replace.sh - 批量文件内容替换工具
# 默认配置
SEARCH_DIR="."
FILE_PATTERN="*.txt"
SEARCH_TEXT=""
REPLACE_TEXT=""
DRY_RUN=false
BACKUP=false
# 显示帮助信息
show_help() {
echo "用法: $0 [选项]"
echo "选项:"
echo " -d, --directory DIR 指定搜索目录 (默认: 当前目录)"
echo " -p, --pattern PAT 文件匹配模式 (默认: *.txt)"
echo " -s, --search TEXT 要搜索的文本 (必需)"
echo " -r, --replace TEXT 替换的文本 (必需)"
echo " -n, --dry-run 只显示将要替换的文件,不实际执行"
echo " -b, --backup 备份原文件"
echo " -h, --help 显示此帮助信息"
exit 0
}
# 解析命令行参数
while [[ $# -gt 0 ]]; do
case $1 in
-d|--directory) SEARCH_DIR="$2"; shift 2 ;;
-p|--pattern) FILE_PATTERN="$2"; shift 2 ;;
-s|--search) SEARCH_TEXT="$2"; shift 2 ;;
-r|--replace) REPLACE_TEXT="$2"; shift 2 ;;
-n|--dry-run) DRY_RUN=true; shift ;;
-b|--backup) BACKUP=true; shift ;;
-h|--help) show_help ;;
*) echo "未知选项: $1"; show_help ;;
esac
done
# 验证必需参数
if [[ -z "$SEARCH_TEXT" ]] || [[ -z "$REPLACE_TEXT" ]]; then
echo "错误: 必须指定搜索文本和替换文本"
show_help
fi
# 主替换逻辑
echo "开始在 $SEARCH_DIR 中搜索 $SEARCH_TEXT..."
echo "文件模式: $FILE_PATTERN"
# 查找并处理文件
while IFS= read -r -d '' file; do
if grep -q "$SEARCH_TEXT" "$file"; then
echo "找到匹配文件: $file"
if [[ "$DRY_RUN" == true ]]; then
echo " [模拟] 将替换: $SEARCH_TEXT -> $REPLACE_TEXT"
else
if [[ "$BACKUP" == true ]]; then
# 创建备份
cp "$file" "${file}.bak"
echo " 已创建备份: ${file}.bak"
fi
# 执行替换
if sed -i "s/$SEARCH_TEXT/$REPLACE_TEXT/g" "$file"; then
echo " ✓ 替换成功"
else
echo " ✗ 替换失败"
fi
fi
fi
done < <(find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -print0)
echo "处理完成!"
高级用法和注意事项
特殊字符处理
#!/bin/bash # 处理包含特殊字符的文本 SEARCH='http://old.example.com' REPLACE='http://new.example.com' # 使用管道符或分隔符标记 sed -i "s|$SEARCH|$REPLACE|g" file.txt # 或使用 @ 作为分隔符 sed -i "s@$SEARCH@$REPLACE@g" file.txt
进度显示脚本
#!/bin/bash
# 显示进度的批量替换
total=$(find . -type f -name "*.txt" | wc -l)
count=0
for file in $(find . -type f -name "*.txt"); do
((count++))
echo -ne "进度: $count/$total 文件\r"
sed -i 's/old/new/g' "$file"
done
echo -e "\n处理完成!共处理 $total 个文件"
使用技巧
替换前确认
#!/bin/bash
# 安全替换模式
for file in *.txt; do
if grep -q "old_text" "$file"; then
echo "是否替换文件: $file? [y/N]"
read -r answer
if [[ "$answer" == "y" ]] || [[ "$answer" == "Y" ]]; then
sed -i 's/old_text/new_text/g' "$file"
echo "已替换: $file"
fi
fi
done
生成替换报告
#!/bin/bash
# 生成替换报告
log_file="/tmp/replace_$(date +%Y%m%d_%H%M%S).log"
echo "替换报告 - $(date)" > "$log_file"
echo "==================" >> "$log_file"
for file in *.txt; do
if grep -q "old_text" "$file"; then
count=$(grep -c "old_text" "$file")
echo "$file: 替换了 $count 处" >> "$log_file"
sed -i 's/old_text/new_text/g' "$file"
fi
done
echo "报告已保存到: $log_file"
这些方法涵盖了从简单到复杂的批量替换需求,可以根据具体场景选择合适的方案,建议在生产环境使用前先在测试目录进行测试。