当模式为删除命令的换行符时,sed 是否有错误?

当模式为删除命令的换行符时,sed 是否有错误?

我的目标是打印文件的内容直至(并排除)特定模式,并且我使用以下命令按预期工作(即使模式为^$):

sed -n '/pattern/!p;//q' file

为了缩短上述命令(您知道,节省几个字节),我发现我可以“反转”否定的打印命令,而是使用删除,如下所示:

sed '/pattern/d;//q' file  

它再次按预期工作,除非/pattern/引用空行,在/^$/这种情况下它会将空行本身添加到输出中,这很奇怪。

在我的例子中,该文件显然包含一个空行,这就是我想要分割内容的地方。

知道为什么会发生这种情况吗?sed这种极端情况有缺陷吗?(使用大文件时,附加功能//q会立即退出以节省处理时间)

sed --version返回sed (GNU sed) 4.5

答案1

使用 GNU sed 你可以运行

sed '/pattern/Q' file

q命令在退出之前打印模式空间, Q命令默默退出。

我认为否定命令!p避免q打印模式空间。

sed -n '/pattern/!p;//q' file  

-n选项避免q打印模式空间。其他行会被打印,因为地址被取反,因此该p命令适用于除包含 之外的所有行/pattern/。另一种写法是

sed -n '/pattern/q;p' file

当匹配时pattern,退出(由于-n选项,不打印)。所有其他行,打印。

在另一个脚本中,d命令删除所有模式空间并直接转到脚本的开头,sed并从输入中加载新行。

sed '/pattern/d;//q' file  

编辑-在这种情况下,我认为//q当有匹配时永远不会达成。

echo -e 'one\ntwo\nthree\n\nfour\n\n'|sed '/^$/d;//q'
one
two
three
four

可能线路不是空的,跑去cat -vet file看看有没有什么。

sed版本4.7有一个新的选项--debug,它对于了解sed如何工作非常有用。

答案2

经过进一步研究,没有成功的解决方案:

sed '/^$/,$d' file

就紧凑性而言,这是我能找到的最好的,唯一的缺点是它会处理整个file,这在某些情况下可能是不可取的(例如,一个很大的)

sed '/^$/,$d;//q' file

添加典型的退出命令没有帮助,因为较早的范围已经涵盖了整个file

sed '/^$/q' file
sed '/^$/Q' file

这些建议虽然非常紧凑,但并不理想(因为额外的输出/可移植性)

sed -n '/^$/q;p' file

这另一个建议也是我自己发现的,它有点好,因为它会在找到模式后立即退出,尽管我希望摆脱这个-n选项,这是我开始这一切的地方......

相关内容