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

时间:2015-02-18 22:57:22

标签: sed

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

seq 10 > foo.txt

sed '2,7d;3,6d' foo.txt
1
9
10

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

1 个答案:

答案 0 :(得分: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

相比之下,这不是:

sed -e '/2/,/7/d' -e '3,6d' foo.txt

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

  

打败我。我认为给出一些sed的奥术构造,你可能会错过蝙蝠侠符号或命令中间的某些东西,但sed -e '2,7d' -e '3,6d' foo.txt的行为方式相同,交换顺序会产生预期的结果(GNU)关于Cygwin的sed 4.2.2)。 Solaris上的/bin/sed总是产生预期的结果,有趣的是GNU sed 3.02。 Ed Morton

  

更多数据:只有sed才会发生4.2.2如果第二个范围是第一个范围的子集:sed '2,5d;2,5d'显示错误,sed '2,5d;1,5d'和{{1} } 不要。 glenn jackman

GNU sed主页上写着“请将错误报告发送到gnu.org上的bug-sed”(除了它有@代替'at')。你有一个很好的再现;明确你期望的输出与你得到的输出(他们会得到重点,但最好确保他们不会误解)。指出命令的反向排序按预期工作,并将各种其他命令作为工作或不工作的示例。 (您甚至可以将此Q& A URL作为交叉引用,但请确保错误报告是自包含的,以便即使URL后面没有人也可以理解它。)

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

OP指出:

  
      
  • 感谢大家的评论和其他测试。我将向GNU sed提交错误报告并发布他们的回复。 santayana
  •