Ubuntu 22.04中sed替换含反斜杠字符串异常的技术求助
sed替换配置文件时的反斜杠转义问题
问题场景
需要将配置文件中的一行:
define('CIVICRM_LOGGING_DSN', CIVICRM_DSN);
替换为:
define('CIVICRM_LOGGING_DSN', 'myuser:mypassword@localhost:3306\civicrm_uat_logs');
尝试过程与问题
- 首次执行的sed命令:
结果异常,目标字符串丢失了sed -i -e "s/define('CIVICRM_LOGGING_DSN', CIVICRM_DSN);/define('CIVICRM_LOGGING_DSN', 'myuser:mypassword@localhost:3306\civicrm_uat_logs');/" /my_path/civicrm.settings.phpci字符:define('CIVICRM_LOGGING_DSN', myuser:mypassword@localhost:3306 vicrm_uat_logs); - 意识到需要给数据库字符串加引号后,调整命令后无报错,但替换未生效。
环境:Ubuntu 22.04 LTS
问题根源
核心是多层转义冲突:
- shell会先解析双引号中的转义字符,再将内容传递给sed;
- sed本身也会将
\视为转义符,替换字符串中的\c会被sed当作特殊序列处理,导致字符丢失; - 单引号的转义处理不当也会导致匹配或替换失败。
解决方法
方案1:用单引号包裹sed脚本(推荐)
单引号中的内容会被shell原样传递给sed,仅需在sed内部对\转义为\\,同时用'\''转义单引号:
sed -i -e 's/define('\''CIVICRM_LOGGING_DSN'\'', CIVICRM_DSN);/define('\''CIVICRM_LOGGING_DSN'\'', '\''myuser:mypassword@localhost:3306\\civicrm_uat_logs'\'');/' /my_path/civicrm.settings.php
方案2:用双引号包裹,双重转义反斜杠
需要将\写成\\\\(shell解析后变为\\,sed再解析为单个\):
sed -i -e "s/define('CIVICRM_LOGGING_DSN', CIVICRM_DSN);/define('CIVICRM_LOGGING_DSN', 'myuser:mypassword@localhost:3306\\\\civicrm_uat_logs');/" /my_path/civicrm.settings.php
验证结果
执行上述任一命令后,目标行将被正确替换为:
define('CIVICRM_LOGGING_DSN', 'myuser:mypassword@localhost:3306\civicrm_uat_logs');
内容的提问来源于stack exchange,提问作者ChumKui
相关产品推荐
相关产品推荐

