You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Sed转义多行字符串以在另一Sed命令中实现替换

解决多行字符串的sed转义与替换问题

你的核心问题在于原方案用echo处理多行字符串时会丢失换行符,而且sed默认是逐行处理文本的,直接用单行转义逻辑无法匹配多行模式。下面是针对多行场景优化后的完整解决方案:

关键改进点

  • 用printf替代echo来保留多行字符串的换行(echo会自动将换行转为空格,导致多行结构丢失)
  • 扩展转义规则,新增对换行符的转义(让sed能识别多行模式中的换行)
  • 修改sed替换命令,先将整个文件读入模式空间,实现多行匹配替换

修正后的完整代码

#!/bin/bash

# 定义专门处理多行字符串的sed转义函数
escape_sed_pattern() {
  local input="$1"
  # 1. 转义sed特殊字符:[]\/$*.^|
  # 2. 将换行符转义为\n(让sed能识别多行模式)
  printf "%s" "$input" | sed -e 's/[]\/$*.^|[]/\\&/g' -e ':a;N;$!ba;s/\n/\\n/g'
}

# 处理目标匹配字符串
read -r -d '' TARGET_STRING <<'HEREDOC'
$N = "magic_quotes_gpc = <b>"._("On")."</b>";
$D = _("Increase your server security by setting magic_quotes_gpc to 'on'. PHP will escape all quotes in strings in this case.");
$S = _("Search for 'magic_quotes_gpc' in your php.ini and set it to 'On'.");
$R = ini_get('magic_quotes_gpc');
$M = TRUE;
$this->config_checks[] = array("NAME" => $N , "DESC" => $D , "RESULT" => $R , "SOLUTION" => $S , "MUST" => $M );
HEREDOC
ESCAPED_TARGET=$(escape_sed_pattern "$TARGET_STRING")

# 处理替换字符串
read -r -d '' REPLACE_STRING <<'HEREDOC'
/* NOTE: "Magic_quotes_gpc" is no longer required. We taught GOsa2 to deal with it (see /usr/share/gosa/html/main.php). By Questor */
/* Automatic quoting must be turned on */
/*
$N = "magic_quotes_gpc = <b>"._("On")."</b>";
$D = _("Increase your server security by setting magic_quotes_gpc to 'on'. PHP will escape all quotes in strings in this case.");
$S = _("Search for 'magic_quotes_gpc' in your php.ini and set it to 'On'.");
$R = ini_get('magic_quotes_gpc');
$M = TRUE;
$this->config_checks[] = array("NAME" => $N , "DESC" => $D , "RESULT" => $R , "SOLUTION" => $S , "MUST" => $M );
*/
HEREDOC
ESCAPED_REPLACE=$(escape_sed_pattern "$REPLACE_STRING")

# 执行多行替换:先将整个文件读入模式空间,再执行替换
MODIFIED_STRING=$(sed -e ':a;N;$!ba;s/'"$ESCAPED_TARGET"'/'"$ESCAPED_REPLACE"'/g' file_name.txt)

# 输出结果
echo "$MODIFIED_STRING"

代码解释

  1. escape_sed_pattern函数:

    • 用printf "%s"完整保留输入字符串的所有换行和空格
    • 第一部分转义sed的特殊元字符([]\/$*.^|),确保这些字符被当作普通文本处理
    • 第二部分:a;N;$!ba是sed的多行读取技巧:循环读取所有行到模式空间,然后将换行符转义为\n,让sed能识别多行模式中的换行
  2. sed替换命令:

    • :a;N;$!ba同样用于将file_name.txt的全部内容读入模式空间,这样sed就能匹配跨多行的目标字符串
    • 直接使用转义后的目标和替换字符串完成全局替换
  3. 移除原代码的单引号包裹逻辑:

    • 用printf替代echo后,不需要再用单引号包裹来保留首尾空格,因为printf会完整保留原始字符串的格式

内容的提问来源于stack exchange,提问作者Eduardo Lúcio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:17:45