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

如何用Bash Shell将文件中指定文本块替换为其他文件内容

问题描述

我需要将file_to_change.xml中的指定文本块替换为changes.xml的全部内容,待替换的目标块保存在aux.xml中(对应原文件里的一个<client>标签内容)。仅可使用sed、awk这类系统核心工具,不能用外部工具,且与全文件替换的方案不同,仅替换指定块。

各文件内容

file_to_change.xml

<clients>
    <client>
        <name>Bob</name>
        <age>18</age>
    </client>
    <client>
        <name>Alice</name>
        <age>12</age>
    </client>
    <client>
        <name>Carlos</name>
        <age>28</age>
    </client>
</clients>

changes.xml

<client>
        <name>Carlita</name>
        <age>17</age>
    </client>

aux.xml(待替换的目标块)

<client>
        <name>Carlos</name>
        <age>28</age>
    </client>

我尝试过以下命令,但未达到预期效果:

sed -i -e '1r changes.xml' -e '1,/r aux.xml/d' file_to_change.xml

期望修改后的file_to_change.xml内容:

<clients>
    <client>
        <name>Bob</name>
        <age>18</age>
    </client>
    <client>
        <name>Alice</name>
        <age>12</age>
    </client>
    <client>
        <name>Carlita</name>
        <age>17</age>
    </client>
</clients>
解决方案

方法1:使用awk实现

通过awk读取目标块和替换内容到内存,遍历原文件时匹配目标块并替换,其他内容正常输出:

awk '
BEGIN {
    # 读取aux.xml目标块存入target
    while (getline line < "aux.xml") {
        target = target line "\n"
    }
    # 读取changes.xml替换内容存入replace
    while (getline line < "changes.xml") {
        replace = replace line "\n"
    }
    close("aux.xml")
    close("changes.xml")
    current = ""
}
{
    current = current $0 "\n"
    # 匹配到目标块则输出替换内容,清空累积
    if (current == target) {
        print replace
        current = ""
    } else if (length(current) > length(target)) {
        # 累积内容过长未匹配,逐行输出前面的内容
        while (length(current) > length(target)) {
            n = index(current, "\n")
            print substr(current, 1, n-1)
            current = substr(current, n+1)
        }
    }
}
END {
    # 输出剩余内容
    printf "%s", current
}
' file_to_change.xml > temp.xml && mv temp.xml file_to_change.xml

方法2:使用sed实现(针对固定目标块)

直接针对目标块的多行内容进行匹配和替换,适合目标块固定的场景:

sed -i '
/<client>/{
    N
    N
    N
    N
    # 匹配目标块的5行内容
    /    <client>\n        <name>Carlos<\/name>\n        <age>28<\/age>\n    <\/client>/{
        # 替换为changes.xml的内容
        c\    <client>\n        <name>Carlita<\/name>\n        <age>17<\/age>\n    <\/client>
    }
}
' file_to_change.xml

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:15:29