用 sed 替换更大部分中的某个部分中的单词?

Substitute a word in a section within a bigger section with sed?

我意识到 sed 可以在多行上进行模式匹配。是否可以替换这些多行的特定部分中的单词?例如

file begins
random line
>>starting line block
    random line
    random line
    .....
    >>replace from here
     hello
     hi there hello
    >>stop replacing here
    more random stuff
>>finishing line block 
more random lines
file ends

假设我想用 'bye' 替换 'hello' 但只能在 'replace from here' 到 'stop replacing here' 之间,而且只能在 'starting line block' 到 [=23= 之间].是否可以使用 sed 就地执行此操作?例如

sed '/starting line block/,/finishing line block/ /replace from here/,/stop replacing here/ s/hello/bye/g/'

您可以为此使用块,如以下 sed 脚本所示:

/start/,/end/ {
    /from/,/to/s/foo/bar/g
}

运行 它与 sed -f <script> "$file".

{} 括号分隔命令块,/start/,/end/ 是命令将 运行 用于的行范围。在这种情况下,我们有一个命令 s/foo/bar/g,我们对每个块中 /from/,/to/ 范围内的每一行 运行。

上面的 运行 s/foo/bar/g 也在带有 fromto 分隔符的行上。我猜应该没问题。

如果多个行范围匹配 /start/,/end//from/,/to/,这也有效。

下面的一行也适用于 GNU 和(至少一个)BSD sed。 POSIX 没有指定 ; 来分隔命令,并且在结束 } (link to spec.) 之前需要一个换行符,所以它可能不太便携。

sed '/start/,/end/{/from/,/to/s/foo/bar/g;}' "$file"

如果您在解析 XML 或 HTML 时应该小心,正如评论中的某些人指出的那样。 Here's one answer that seems to be pretty famous, though there's also this。根据您的要求和输入数据,实用主义最终可能会获胜,尤其是一次性的。