替换字符串


替换指定字符串


#!/bin/bash

# 检查参数数量(至少 3 个参数:目录、要替换的字符串、替换后的字符串,后跟文件列表)
if [ $# -lt 3 ]; then
    echo "用法: $0 <目录路径> <要替换的字符串> <替换后的字符串> [文件1] [文件2] ..."
    echo "示例: $0 ./dir 'old string' 'new string' file1.txt file2.conf"
    exit 1
fi

# 解析参数
directory="$1"
old_string="$2"
new_string="$3"
shift 3  # 移除前三个参数,剩下的为文件列表

timestamp=$(date +%Y%m%d%H%M%S)

# 处理每个指定的文件
for file in "$@"; do
    full_path="${directory}/${file}"  # 拼接完整路径
    if [ ! -f "$full_path" ]; then
        echo "错误:文件 $full_path 不存在或不是普通文件"
        continue
    fi

    # 备份文件(以时间戳结尾)
    backup_file="${full_path}_${timestamp}"
    cp "$full_path" "$backup_file"
    echo "已备份文件:$full_path$backup_file"

    # 替换字符串(处理特殊字符,使用 sed 的 -e 选项并转义特殊字符)
    # 注意:这里使用双引号包裹 sed 命令,以便 $old_string 和 $new_string 中的变量被正确解析
    # 对特殊字符(如引号、分号)进行转义,避免 sed 语法错误
    escaped_old=$(echo "$old_string" | sed 's/[&\/]/\\&/g; s/[^[:alnum:]]/\\&/g')
    escaped_new=$(echo "$new_string" | sed 's/[&\/]/\\&/g; s/[^[:alnum:]]/\\&/g')
    sed -i -e "s|${escaped_old}|${escaped_new}|g" "$full_path"
    echo "已完成替换:$full_path"

    # 验证:打印替换前后的前 5 行(标记替换内容)
    echo "------------------------"
    echo "验证文件:$full_path"
    echo "替换前(备份文件):"
    head -n 5 "$backup_file" | sed -e "s|${escaped_old}|[OLD: ${old_string}]|g"
    echo "替换后:"
    head -n 5 "$full_path" | sed -e "s|${escaped_new}|[NEW: ${new_string}]|g"
    echo "------------------------"
done

echo "所有指定文件处理完成!"