![当模式为删除命令的换行符时,sed 是否有错误?](https://linux22.com/image/1577641/%E5%BD%93%E6%A8%A1%E5%BC%8F%E4%B8%BA%E5%88%A0%E9%99%A4%E5%91%BD%E4%BB%A4%E7%9A%84%E6%8D%A2%E8%A1%8C%E7%AC%A6%E6%97%B6%EF%BC%8Csed%20%E6%98%AF%E5%90%A6%E6%9C%89%E9%94%99%E8%AF%AF%EF%BC%9F.png)
我的目标是打印文件的内容直至(并排除)特定模式,并且我使用以下命令按预期工作(即使模式为^$
):
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
选项,这是我开始这一切的地方......