Shell脚本如何批量替换文件内容

wen 实用脚本 8

本文目录导读:

Shell脚本如何批量替换文件内容

  1. 使用 sed 命令(最常用)
  2. 使用 find + sed 组合(推荐)
  3. 使用 awk 命令
  4. 完整的批量替换脚本示例
  5. 高级用法和注意事项
  6. 使用技巧

我来介绍几种在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"

这些方法涵盖了从简单到复杂的批量替换需求,可以根据具体场景选择合适的方案,建议在生产环境使用前先在测试目录进行测试。

抱歉,评论功能暂时关闭!