比方说,我有这个包含 500 行文本的文件。
one
two
three
four
five
six
seven
eight
nine
ten
.
.
.
five-hundred
Run Code Online (Sandbox Code Playgroud)
如果我想用某个字符串替换匹配后的第五行,我会这样做:
sed '/two/{n;n;n;n;n;s/.*/MODIFIED/}' inputfile
Run Code Online (Sandbox Code Playgroud)
输出:
one
two
three
four
five
six
MODIFIED
eight
nine
ten
.
.
.
five-hundred
Run Code Online (Sandbox Code Playgroud)
但是如果我想在匹配后替换第 60 行呢?我不想写 'n' 次。
我尝试使用 x、h/H、g/G 和范围,但仍然无法获得所需的输出。
我有以下 sed 表达式:
echo 'abcabcabc' | sed -n ':-A s/a/x/1; s/a/&/2;t-A; p'
Run Code Online (Sandbox Code Playgroud)
据说应该用除最后一个之外'a'
的所有出现替换。'x'
所以,预期的输出是这样的:
xbcxbcabc
Run Code Online (Sandbox Code Playgroud)
但实际输出是这样的:
xbcxbcxbc
Run Code Online (Sandbox Code Playgroud)
将全部替换'a'
为'x'
我知道已经有类似的问题了,比如 替换每行中除最后一个字符之外的每个字符
但我在这里尝试使用 sed 条件分支的不同方法。
让我用我自己的理解来分解我的 sed 表达式
首先是 sed 表达式:
xbcxbcabc
Run Code Online (Sandbox Code Playgroud)
sed 将其拉abcabcabc
入模式空间
然后设置一个标签:-A
然后s/a/x/1;
将第一次出现的 替换'a'
为'x'
。现在模式空间包含这个xbcabcabc
s/a/&/2;
检查模式空间是否包含两个'a'
,它确实包含两个 ,因此它'a'
用它们自己替换这两个&
。所以模式空间仍然包含这个xbcabcabc
t-A
由于最近的替换成功,跳回标签-A
从标签开始,-A
它再次执行此操作s/a/x/1;
,将模式空间的内容从 this 变为xbcabcabc
thisxbcxbcabc
s/a/&/2
它检查是否还有两个'a'
。这次模式空间包含 thisxbcxbcabc …