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

使用Bash的sed替换文件内容遇报错,求非正则解决方案

解决sed替换多行文本时的"unterminated `s' command"错误

问题场景

尝试用Bash脚本的sed功能替换文件内容,不想使用正则表达式,但执行脚本时出现错误:sed: -e expression #1, char 7: unterminated s' command`

输入内容

<if property="headless">
        <VMArg name="-Djava.awt.headless=true"/>
    </if>

    <VMArg name="-Dfile.encoding=UTF-8"/>
    <VMArg name="-Djava.util.logging.config.file=$VDISTDIR/system/conf/logging.properties"/>
    <VMArg name="-Dlog4j.configurationFile=file:///$VDISTDIR/system/conf/log4j2.yaml"/>

期望输出

<if property="headless">
        <VMArg name="-Djava.awt.headless=true"/>
    </if>
This is the replaced text
    <VMArg name="-Dfile.encoding=UTF-8"/>
    <VMArg name="-Djava.util.logging.config.file=$VDISTDIR/system/conf/logging.properties"/>
    <VMArg name="-Dlog4j.configurationFile=file:///$VDISTDIR/system/conf/log4j2.yaml"/>

尝试的错误脚本

#!/bin/bash
find='<if property="headless">
        <VMArg name="-Djava.awt.headless=true"/>
    </if>

    <VMArg name="-Dfile.encoding=UTF-8"/>'

replace='<if property="headless">
        <VMArg name="-Djava.awt.headless=true"/>
    </if>

    <VMArg name="-Dfile.encoding=UTF-8"/>'

sed "s/$find/$replace/g" filename.input

错误原因

  1. 多行文本破坏命令结构:find和replace变量包含换行符,直接代入sed的s命令时,换行会被解析为命令结束,导致sed认为s命令未完成,触发"unterminated `s' command"错误。
  2. 分隔符冲突:sed默认用/作为s命令的分隔符,而文本中存在大量/(比如file:///),会提前截断命令,引发语法错误。
  3. 替换内容未达标:原脚本的replace变量没有添加期望的This is the replaced text,无法实现目标输出效果。

解决方案

方案一:直接追加文本(推荐)

不需要替换大块多行文本,精准匹配</if>所在行,在其后插入目标文本即可,这种方式简洁且避免多行处理的问题:

#!/bin/bash
sed '/    <\/if>/a\This is the replaced text' filename.input

脚本说明

  • / <\/if>/:精确匹配 </if>这一行(注意转义/为\/)
  • a\:sed的追加命令,在匹配行的下一行插入指定文本

方案二:多行替换(如需替换整块内容)

改用|作为s命令的分隔符,并将变量中的换行符转义为\n,确保sed正确解析:

#!/bin/bash
find='<if property="headless">\n        <VMArg name="-Djava.awt.headless=true"/>\n    </if>\n\n    <VMArg name="-Dfile.encoding=UTF-8"/>'
replace='<if property="headless">\n        <VMArg name="-Djava.awt.headless=true"/>\n    </if>\nThis is the replaced text\n    <VMArg name="-Dfile.encoding=UTF-8"/>'

sed -e "s|$find|$replace|g" filename.input

脚本说明

  • 用|替代/作为分隔符,避免与文本中的/冲突
  • 将变量中的换行符替换为\n,并使用-e参数确保sed正确解析转义字符

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:31:01