root@u1804:~# sed --version
sed (GNU sed) 4.5
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Jay Fenlason, Tom Lord, Ken Pizzini,
and Paolo Bonzini.
GNU sed home page: <https://www.gnu.org/software/sed/>.
General help using GNU software: <https://www.gnu.org/gethelp/>.
E-mail bug reports to: <[email protected]>.
root@u1804:~#
我是 sed 的新手,我根据我的理解在 sed 的工作流程下创建了(如果您发现任何错误,请纠正我)。
因此,模式空间的默认自动打印似乎总是在末尾包含一个换行符。我的问题是,是否也会p
包含换行符?我有以下例子。
root@u1804:~# seq 3 | sed -rn 'p'
1
2
3
root@u1804:
这里每个数字末尾的换行符是由 sed 自己添加的(参见图表“将换行符添加回模式空间”)。所以它似乎p
不会附加换行符。但是,请参见下面的示例。
root@u1804:~# seq 3 | sed -rn 'x;p;x;p'
1
2
3
root@u1804:~#
这里x
用保持空间交换模式空间,这将导致一个空的模式空间。现在p
应用于模式空间(其中没有任何内容)应该什么都不打印。但根据结果,这里似乎p
打印了一个换行符。对我来说,这似乎是不一致的行为。谁能解释一下?
要回答您的主要问题:
GNU将在执行命令时
sed
附加一个字符,除非输入行缺少其终止字符(请参阅下面关于行的说明)。<newline>
p
<newline>
据我所知,
sed
'p
标志及其自动打印功能实现了相同的逻辑来输出模式空间:如果尾随<newline>
字符被删除,则将其添加回来;否则他们不会。例子:
在这两种情况下,对于没有字符的输入行,输出中都没有
<newline>
字符 (0a
)。关于您的图表:
“将换行符添加到模式空间”可能不准确,因为该
<newline>
字符未放入模式空间1。此外,该步骤与-n
选项无关 - 但这不会使图表出错;相反,它可能应该合并到“打印模式空间”中。不过,我同意你关于文档不够清晰的观点。
1您在自己的答案中引用的句子“模式空间的内容被打印到输出流中,如果删除了尾随换行符,则添加回”,这意味着附加到流中,而不是模式空间中。当然,由于花样空间很快就被清除了,这是一个非常次要的点
<newline>
关于涉及
x
标志的测试:在内部,模式空间和保持空间是结构,“我的尾随
<newline>
字符被丢弃了吗?” 是他们的一员。我们称它为chompedsed
(顺便说一下,它在 的源代码中命名)。模式空间由读取行填充,其chomped属性取决于该行的终止方式:
true
如果它以<newline>
字符结尾,false
否则。另一方面,保持空间被初始化为空,并且它的chomped属性被设置为true
。因此,当您交换模式空间和保持空间并打印最初的保持和现在的模式时,
<newline>
会打印一个字符。示例 - 这些命令具有相同的输出:
(我只是简单地看了一下
sed
's 的代码,所以这很可能不准确)。关于行(澄清从对您的答案的评论开始):
不用说,没有终止字符的行
<newline>
是一个有问题的概念。引用POSIX:此外,POSIX定义了一个文本文件:
最后,POSIX on
sed
(bold mine):不过, GNU
sed
在定义其输入时似乎不那么严格:所以,关于我的第一句话,我们应该考虑到,对于 GNU
sed
,读入模式空间的内容不一定是格式良好的文本行。我编辑了我的答案,只包含一个基于 fra-san 答案的更新图表。唯一目的是供新的 sed 用户参考。
在 GNU sed 中:该命令
p
仅在源文本中添加一个尾随换行符(当放置在模式空间中时从输入中删除一个),但如果将其他文本打印到同一流中,也会添加一个前导换行符。仅在最后一行的输入中可能缺少尾随换行符。
仅打印最后一行,仅当源文件在最后一行已经有换行时才会有新行:
来自信息 sed:
其他一些 sed 版本可能会添加尾随换行符和/或发出警告。