使用sed删除文件行 - 意外行为

san*_*ana 11 sed

我发现有些奇怪的东西,而不是用sed搞笑.如果尝试从文件中删除多个行间隔(按编号),但列表中稍后指定的任何间隔完全包含在列表中较早的时间间隔内,则在指定的(较大)间隔后将删除另一行.

seq 10 > foo.txt

sed '2,7d;3,6d' foo.txt
1
9
10
Run Code Online (Sandbox Code Playgroud)

这种行为背后是一个烦人的错误,因为在我的脚本中,我动态生成间隔端点,在某些情况下,产生的间隔是多余的.我可以清理它,但我想不出为什么sed会故意这样做的一个很好的理由.

Jon*_*ler 5

由于这个问题在2015-02-24的Stack Overflow Weekly Newsletter电子邮件中突出显示需要回答,我将上述评论(提供答案)转换为正式答案.这里的未归属评论是我以基本相同的形式提出的.

感谢您提供简明扼要的完整问题.结果很有趣.我可以用你的脚本重现它.有趣的是,sed '3,6d;2,7d' foo.txt(以相反顺序执行删除操作)产生预期答案,其中包含8输出.这使它看起来可能是(GNU)中的可报告错误sed,特别是因为BSD sed(在Mac OS X 10.10.2 Yosemite上)可以正常运行任何顺序的操作.我使用Ubuntu 14.04衍生版的'sed(GNU sed)4.2.2进行了测试.

为您/他们提供更多数据点.这两个包括输出中的8个:

sed -e '/2/,/7/d' -e '/3/,/6/d' foo.txt
sed -e '2,7d' -e '/3/,/6/d' foo.txt
Run Code Online (Sandbox Code Playgroud)

相比之下,这不是:

sed -e '/2/,/7/d' -e '3,6d' foo.txt
Run Code Online (Sandbox Code Playgroud)

后者让我感到惊讶(甚至接受了基本的错误).

甘拜下风.我认为给出一些sed神秘的构造,你可能会错过蝙蝠侠符号或命令中间的某些东西,但sed -e '2,7d' -e '3,6d' foo.txt行为方式相同,交换顺序会产生预期的结果(sedCygwin上的GNU 4.2.2)./bin/sed在Solaris上总是产生预期的结果,有趣的是GNU sed3.02 也是如此.埃德莫顿

更多数据:sed如果第二个范围是第一个范围的子集,它似乎只发生在4.2.2:sed '2,5d;2,5d'显示错误,sed '2,5d;1,5d'sed '2,5d;2,6d'不是.格伦杰克曼

GNUsed主页上说:"请发送错误报告的bug-SID位于gnu.org"(除非它有"为"到位的@).你有一个很好的再现; 明确你期望的输出与你得到的输出(他们会得到重点,但最好确保他们不会误解).指出命令的反向排序按预期工作,并将各种其他命令作为工作或不工作的示例.(您甚至可以将此问答URL作为交叉引用,但请确保错误报告是自包含的,以便即使网址后面没有人也可以理解它.)

您还可以指向BSD sed(以及Solaris版本和旧版GNU 3.02 sed),其行为与预期的一样.随着旧版GNU sed工作,这意味着这可以说是回归.[...经过一些实验...] 4.1版本发生破损; 4.0.9版本没问题.(我还检查了4.1.5和4.2.1;两者都被破坏了.)如果他们想通过查看改变的内容找到麻烦,这将有助于维护人员.

OP指出:

  • 感谢大家的评论和其他测试.我将向GNU提交一份错误报告sed并发布他们的回复.桑塔亚纳