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

使用sed修改XML文件端口失败原因排查及有效命令分享

Why Your Initial sed Command Failed (And the Fix Explained)

Let's break down exactly why your first sed command didn't make any changes, then walk through why the working command you found gets the job done right.

Issues with the Original sed Command

Your initial attempt was:

sed "s|\(\"^[[:space:]]*.+port[[:space:]]+protocol=.+port=\"\).*|\1\"3022\"/>|" inputfile

Here's what went wrong:

  1. No -E flag for Extended Regular Expressions (ERE)
    By default, sed uses Basic Regular Expressions (BRE), where syntax like .+ (one or more of any character) and + (repetition) isn't recognized. Your grep -E worked because -E enables ERE—but your sed command skipped this flag, so the regex couldn't match your target line at all.

  2. Invalid leading quote in the capture group
    Your capture group starts with \"^[[:space:]]*—that leading quote doesn't exist in your target line (<port protocol="tcp" port="22"/> starts with <, not a quote). This broke the match before it even got started.

  3. Overcomplicated and misaligned capture group logic
    Even if you fixed the above issues, the regex was overengineering the pattern match. It tried to wrap a chunk of the line that doesn't align with the actual structure of your XML, making it impossible to correctly target the port="22" segment you wanted to change.

Why the Working sed Command Works

The command you discovered hits all the right marks:

sed -E '/short/,/service/ s/port=[^<]*/port=\"3022\"/>/' inputfile

Let's unpack it:

  1. -E enables ERE
    This lets you use the same flexible regex syntax that made your grep -E successful, avoiding the limitations of BRE.

  2. Address range: /short/,/service/
    This targets only the lines between (and including) the line with <short>SSH</short> and the closing </service> tag. This ensures you only modify the SSH service's port, not any other service entries if your XML file had multiple.

  3. Substitution pattern: s/port=[^<]*/port=\"3022\"/>/

    • port=[^<]* matches port= followed by any characters except <—since your line ends with />, this grabs exactly the port="22" segment you want to replace.
    • It swaps that matched text with port="3022"/>, cleanly updating the port number while keeping the rest of the line's structure intact.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:03:29