使用sed精准替换含特殊字符的PHP变量赋值行


阅读 2 次

问题场景分析

在PHP项目开发中,我们经常需要批量修改配置文件。最近在维护一个缓存系统时,遇到需要修改cache.php中的缓存目录配置:

$cache_directory = './cache';

需要将其动态替换为变量$new_cache_directory的值,同时面临两个技术难点:

  • 路径字符串包含特殊字符./
  • 相同字符串在文件中多次出现但只需修改特定行

sed解决方案

使用sed的精确匹配模式,通过整行匹配避免误替换:

sed -i "s/^\$cache_directory = '\.\/cache';$/\$cache_directory = \$new_cache_directory;/" cache.php

关键点解析:

^            # 行首锚定
\$           # 转义$符号
\.\/         # 转义.和/符号
$            # 行尾锚定

Bash完整实现

结合变量传递的完整脚本示例:

#!/bin/bash
new_cache_dir="'/new/path/to/cache'"

sed -i.bak \
-e "s|^\$cache_directory = '\./cache';|\$cache_directory = ${new_cache_dir};|" \
cache.php

# 验证修改
grep -n '$cache_directory' cache.php

安全增强方案

为防止误操作,建议:

# 1. 先备份原文件
cp cache.php cache.php.bak

# 2. 使用dry-run模式测试
sed -n "s/^\$cache_directory = '\.\/cache';/\$cache_directory = \$new_cache_directory;/p" cache.php

# 3. 添加行号确认
grep -n '$cache_directory' cache.php | grep "\./cache"

替代方案对比

当处理复杂替换时,也可以考虑:

# 使用perl模式
perl -i -pe "s/\Q\$cache_directory = './cache'/\E\$cache_directory = \$new_cache_directory/" cache.php

# 使用awk处理
awk -v new_dir="$new_cache_dir" \
'/\$cache_directory = \x27\.\/cache\x27;/ {$0="$cache_directory = "new_dir";"}1' \
cache.php > temp && mv temp cache.php