除了明显的语法点b
可以接受标签而不能接受标签n
,并且要在b
没有标签的情况下使用,您需要将其放置在传递的参数的末尾-e
(至少对于单行程序)...ab
没有label 和 ann
似乎做同样的事情。
这真的是真的,还是有我没有注意到的细微差别?他们在什么条件下做同样的事情,在什么条件下他们不做?
这两个例子是相同的,只是n
被替换了b
。可以看到输出不同:
$ echo $'1\n2\n3' | sed 's/./AA/; n; s/./BB/'
AA
BB
AA
$ echo $'1\n2\n3' | sed 's/./AA/; b; s/./BB/'
AA
AA
AA
Run Code Online (Sandbox Code Playgroud)
b
分支到命令的末尾。 n
继续执行剩余的命令。因此,对于b
,s/./BB/
永远不会执行替换。使用n
,每隔一行执行一次。
(上述命令是使用 GNU sed 运行的。使用 BSD/OSX sed,正如 OP 所指出的,需要对代码格式进行一些小的更改。)
好吧,让我们看看...
牧场b
命令:
[2addr]b[label]
Branch to :label. If label is not specified, branch to the end of the script.
Run Code Online (Sandbox Code Playgroud)
外部n
命令:
[2addr]n
If auto-print is not disabled, print the pattern space, then, regardless,
replace the pattern space with the next line of input. If no next line of
input is available, branch to the end of the script.
Run Code Online (Sandbox Code Playgroud)
所以这里的主要区别是:
b
无条件分支到脚本末尾
n
如果没有更多输入,则仅分支到脚本末尾
假设输入如下:
fdue
four
four
fdue
four
Run Code Online (Sandbox Code Playgroud)
我想替换为f
,t
但仅在匹配的行上替换为four
,而在所有其他行上替换u
为i
。一种方法是
sed '/four/{s/f/t/;b;};s/u/i/' infile
Run Code Online (Sandbox Code Playgroud)
输出如预期的那样
fdie
tour
tour
fdie
tour
Run Code Online (Sandbox Code Playgroud)
n
现在,让我们看看使用而不是时会发生什么b
:
fdie
tour
foir
fdie
tour
Run Code Online (Sandbox Code Playgroud)
第二行匹配four
被编辑为foir
而不是tour
因为简单的原因n
不会返回到脚本的顶部。相反,处理s
该行之后的命令n
甚至认为这不是有意的。然而,在最后一行,仅进行了第一次替换,因此不再执行 s
后面的命令。n
总而言之,如果满足以下条件,这两个命令在功能上是等效的:
n
)或n
不应由n
1之前的命令编辑(换句话说,下一行不是与 关联的地址b
)确实,n
打印当前模式空间并拉入下一行,但b
单独也具有相同的效果:分支到脚本末尾意味着自动打印(除非sed
使用 调用-n
,在这种情况下n
也不会打印),然后自动读取在下一行输入中。正如我所说,主要区别在于n
不会跳转到脚本末尾(并且也不会返回到脚本顶部):sed
仅执行其余命令 - 如果有的话(如果不在最后一行) 。
1
这些命令不会被执行,因为正如我所说,n
不会返回到脚本的顶部;此外,其余命令可能会编辑该行,这是不应该发生的事情。