除了第一次使用sed之外,如何查找和替换每个匹配?

Vil*_*age 3 sed

sed用来查找和替换文本,例如:

set -i 's/a/b/g' ./file.txt
Run Code Online (Sandbox Code Playgroud)

这将替换文件中的每个awith 实例b.我需要添加一个异常,这样就sed替换了awith的每个实例b,除了文件中的第一个外观,例如:

There lived a bird who liked to eat fish.
One day he fly to a tree.
Run Code Online (Sandbox Code Playgroud)

这变为:

There lived a bird who liked to ebt fish.
One dby he fly to b tree.
Run Code Online (Sandbox Code Playgroud)

除了第一次出现之外,如何修改我的sed脚本以仅替换awith的每个实例b

我有GNU sed版本4.2.1.

pot*_*ong 5

这可能适合你(GNU sed):

sed 's/a/b/2g' file
Run Code Online (Sandbox Code Playgroud)

要么

sed ':a;s/\(a[^a]*\)a/\1b/;ta' file
Run Code Online (Sandbox Code Playgroud)

这可以是例如

sed ':a;s/\(\(a[^a]*\)\{5\}\)a/\1b/;ta' file
Run Code Online (Sandbox Code Playgroud)

将开始更换ab5 a


Jan*_*lho 5

您可以使用更复杂的脚本执行更完整的实现:

#!/bin/sed -nf

/a/ {
    /a.*a/ {
        h
        s/a.*/a/
        x
        s/a/\n/
        s/^[^\n]*\n//
        s/a/b/g
        H
        g
        s/\n//
    }

    : loop
    p
    n
    s/a/b/g
    $! b loop
}
Run Code Online (Sandbox Code Playgroud)

这个功能很容易用伪代码解释

if line contains "a"
    if line contains two "a"s
        tmp = line
        remove everything after the first a in line
        swap tmp and line
        replace the first a with "\n"
        remove everything up to "\n"
        replace all "a"s with "b"s
        tmp = tmp + "\n" + line
        line = tmp
        remove first "\n" from line
    end-if

    loop
        print line
        read next line
        replace all "a"s with "b"s
        repeat loop if we haven't read the last line yet
    end-loop
end-if
Run Code Online (Sandbox Code Playgroud)