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

如何用sed/awk/perl批量替换字符串中的多行内容?

多行字符串替换需求(sed/awk/perl实现)

输入文件内容

#-------------------------------------------------------------------------------
    # supply connections
    #-------------------------------------------------------------------------------
    
        connect_supply_net VSS      -ports $port(VSSE)
        connect_supply_net VDDS_CPU -ports $port(VDDP)
        connect_supply_net VDD_CPU  -ports $port(VDDPE)

#-------------------------------------------------------------------------------
# Update states
#-------------------------------------------------------------------------------

期望替换后的内容

#-------------------------------------------------------------------------------
    # supply connections
    #-------------------------------------------------------------------------------
 
    if { [llength $port(VSSE)] > 0 } {
      connect_supply_net VSS -ports $port(VSSE)
    }
    if { [llength $port(VDDP)] > 0 } {
      connect_supply_net VDDS_CPU -ports $port(VDDP)
    }
    if { [llength $port(VDDPE)] > 0 } {
      connect_supply_net VDD_CPU -ports $port(VDDPE)
    }

    #-------------------------------------------------------------------------------
    # Update states
    #-------------------------------------------------------------------------------

尝试过的失败命令

之前尝试用sed配合shell变量实现,但未成功:

old_string="connect_supply_net VSS      -ports $port(VSSE)
connect_supply_net VDDS_CPU -ports $port(VDDP)
connect_supply_net VDD_CPU  -ports $port(VDDPE)"

new_string="if { [llength $port(VSSE)] > 0 } {
  connect_supply_net VSS -ports $port(VSSE)
}
if { [llength $port(VDDP)] > 0 } {
  connect_supply_net VDDS_CPU -ports $port(VDDP)
}
if { [llength $port(VDDPE)] > 0 } {
  connect_supply_net VDD_CPU -ports $port(VDDPE)
}"

sed -i ":a;N;$!ba;s/${old_string}/${new_string}/g" file.txt

失败原因

  1. Shell会自动展开$port(VSSE)这类变量,导致传递给sed的内容偏离预期
  2. old_string中的多空格、new_string中的[/]/{/}等特殊字符会被sed当作正则元字符解析,破坏替换逻辑
  3. 多行变量在Shell中传递时容易出现换行符解析异常

简便实现方法

方法1:awk(最直观易维护)

awk可以逐行匹配目标内容,动态生成替换代码,无需复杂转义:

awk '
    /^        connect_supply_net/ {
        split($0, arr, /[[:space:]]+/);
        net = arr[2];
        port = substr(arr[4], 6, length(arr[4])-7); # 提取$port(XXX)里的XXX部分
        printf "    if { [llength $port(%s)] > 0 } {\n", port;
        printf "      connect_supply_net %s -ports $port(%s)\n", net, port;
        print "    }";
        next;
    }
    {print}
' file.txt > temp.txt && mv temp.txt file.txt

说明:

  • 匹配以8个空格开头的connect_supply_net行
  • 拆分每行内容,提取网络名和端口标识
  • 按模板生成带判断逻辑的代码块
  • 通过临时文件替换原文件(避免awk直接修改原文件的兼容性问题)

方法2:修正后的sed方案

如果坚持用sed,需解决变量展开和特殊字符转义问题:

# 用单引号定义字符串,避免Shell解析$port变量
old_string='connect_supply_net VSS      -ports \$port(VSSE)
connect_supply_net VDDS_CPU -ports \$port(VDDP)
connect_supply_net VDD_CPU  -ports \$port(VDDPE)'

new_string='if { \[llength \$port(VSSE)\] > 0 } {
  connect_supply_net VSS -ports \$port(VSSE)
}
if { \[llength \$port(VDDP)\] > 0 } {
  connect_supply_net VDDS_CPU -ports \$port(VDDP)
}
if { \[llength \$port(VDDPE)\] > 0 } {
  connect_supply_net VDD_CPU -ports \$port(VDDPE)
}'

# 转义sed特殊字符,处理换行符
old_escaped=$(printf '%s\n' "$old_string" | sed 's/[\/&]/\\&/g')
new_escaped=$(printf '%s\n' "$new_string" | sed 's/[\/&]/\\&/g')

sed -i ":a;N;$!ba;s/$old_escaped/$new_escaped/g" file.txt

说明:

  • 单引号定义字符串防止Shell展开变量
  • 转义[/]/$等字符,避免sed当作正则元字符
  • 用N命令读取整个文件为单行,实现多行匹配替换

方法3:perl(简洁灵活)

perl支持多行模式,处理特殊字符更友好:

perl -0777 -i -pe '
    s/        connect_supply_net VSS      -ports \$port\(VSSE\)\n        connect_supply_net VDDS_CPU -ports \$port\(VDDP\)\n        connect_supply_net VDD_CPU  -ports \$port\(VDDPE\)/    if { [llength $port(VSSE)] > 0 } {\n      connect_supply_net VSS -ports $port(VSSE)\n    }\n    if { [llength $port(VDDP)] > 0 } {\n      connect_supply_net VDDS_CPU -ports $port(VDDP)\n    }\n    if { [llength $port(VDDPE)] > 0 } {\n      connect_supply_net VDD_CPU -ports $port(VDDPE)\n    }/g
' file.txt

说明:

  • -0777让perl读取整个文件作为单行处理,支持多行匹配
  • -i参数直接修改原文件
  • 精准匹配目标多行内容,替换为期望的代码块

内容的提问来源于stack exchange,提问作者santy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:02:04