删除具有sed的文件行-意外行为

删除具有sed的文件行-意外行为,sed,Sed,我在和塞德鬼混的时候发现了一些奇怪的事情。如果尝试从文件中删除多行间隔(按编号),但列表中稍后指定的任何间隔都完全包含在列表中较早的间隔内,则在指定的(更大的)间隔后会删除额外的单行 seq 10 > foo.txt sed '2,7d;3,6d' foo.txt 1 9 10 这种行为对我来说是一个恼人的错误,因为在我的脚本中,我动态地生成了间隔端点,在某些情况下,生成的间隔是多余的。我可以澄清这一点,但我想不出一个好的理由来解释为什么sed会故意这样做。因为这个问题在2015-02

我在和塞德鬼混的时候发现了一些奇怪的事情。如果尝试从文件中删除多行间隔(按编号),但列表中稍后指定的任何间隔都完全包含在列表中较早的间隔内,则在指定的(更大的)间隔后会删除额外的单行

seq 10 > foo.txt

sed '2,7d;3,6d' foo.txt
1
9
10
这种行为对我来说是一个恼人的错误,因为在我的脚本中,我动态地生成了间隔端点,在某些情况下,生成的间隔是多余的。我可以澄清这一点,但我想不出一个好的理由来解释为什么sed会故意这样做。

因为这个问题在2015-02-24的Stack Overflow每周通讯电子邮件中被强调为需要回答,所以我将上述评论(提供答案)转换为正式答案。我在这里以基本上相同的形式发表了未发表的评论

谢谢你提出一个简洁、完整的问题。结果很有趣。我可以用你的剧本复制它。有趣的是,
sed'3,6d;2,7d'foo.txt
(以相反顺序执行删除操作)生成预期答案,输出中包含8。这使得它看起来可能是(GNU)
sed
中的一个可报告错误,特别是当BSD
sed
(在Mac OS X 10.10.2 Yosemite上)能够正确地按任意顺序运行时。我使用Ubuntu14.04版本的“sed(GNUSED)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
后者让我吃惊(甚至接受了基本的bug)


我不知道。我认为给定一些
sed
的神秘构造,您可能在命令中间缺少蝙蝠侠符号或其他东西,但是
sed-e'2,7d'-e'3,6d'foo.txt
的行为方式相同,交换顺序会产生预期的结果(Cygwin上的GNU
sed
4.2.2)/bin/sed总是产生预期的结果,有趣的是GNU
sed
3.02也是如此


更多数据:如果第二个范围是第一个范围的子集,则似乎只有
sed
4.2.2才会发生:
sed'2,5d;2,5d'
显示错误,
sed'2,5d;1,5d'
sed'2,5d;2,6d'
请勿使用

主页上写着“请将bug报告发送到gnu.org上的bug sed”(除非它用@代替了“at”)。你的生殖能力很好;明确你期望的输出与你得到的输出(他们会明白重点,但最好确保他们不会误解)。指出命令的反向顺序按预期工作,并给出各种其他命令作为工作或不工作的示例。(您甚至可以将此问答URL作为交叉引用,但请确保错误报告是自包含的,这样即使没有人关注该URL,也可以理解它。)

您还可以指向BSD
sed
(以及Solaris版本和较旧的GNU 3.02
sed
)的行为符合预期。随着旧版本GNU-sed的运行,这意味着这可以说是一种倒退。[…经过一点实验…]4.1版本中出现了破损;4.0.9版本还可以。(我还检查了4.1.5和4.2.1;两者都坏了。)如果维护人员想通过查看更改的内容来发现问题,这将有助于他们

OP注意到:

  • 感谢大家的评论和额外的测试。我将向GNU
    sed
    提交一份bug报告,并发布他们的回复

欢迎来到堆栈溢出。谢谢你提出一个简洁、完整的问题。结果很有趣。我可以用你的剧本重新编排。有趣的是,
sed'3,6d;2,7d'foo.txt
(以相反顺序执行删除操作)生成预期答案,输出中包含8。这让它看起来像是(GNU)
sed
(我使用Ubuntu 14.04衍生版本的“sed(GNU-sed)4.2.2”进行了测试)中的一个可报告错误,尤其是当BSD
sed
(在Mac OS X 10.10.2 Yosemite上)能够正确地处理任意顺序的操作时。真是太棒了。我认为给定一些seds的神秘构造,您可能在命令中间缺少蝙蝠侠符号或其他东西,但sed-e'2,7d'-e'3,6d'foo.txt的行为方式相同,交换顺序会产生预期的结果(cygwin上的GNU sed 4.2.2)/Solaris上的bin/sed总是产生预期的结果,有趣的是GNU sed 3.02也是如此。主页上说“请将错误报告发送到GNU.org上的bug sed”(除非它有一个
@
代替了“at”)。你的生殖能力很好;明确你期望的输出与你得到的输出(他们会明白重点,但最好确保他们不会误解)。指出命令的逆序按预期工作。您还可以指向BSD
sed
(以及Solaris版本和较旧的GNU 3.02
sed
)的行为符合预期。在旧版本GNU
sed
运行的情况下,这意味着这可以说是一种回归。您/他们需要更多的数据点:
sed-e'/2/,/7/d'-e'/3/,/6/d'foo.tst
在输出中包括8,sed-e'2,7d'-e'/3/,/6/d'foo.tst;相比之下,
sed-e'/2/,/7/d'-e'3,6d'foo.tst
。后者让我感到惊讶(甚至接受了基本的bug)。更多数据:如果第二个范围是第一个范围的子集,那么sed 4.2.2似乎只会出现:
sed'2,5d;2,5d'
显示错误,
sed'2,5d;1,5d'
sed'2,5d;2,6d'
不感谢您将这些放在一起。我已经得到GNU sed的确认,这确实是一个bug,他们给我发送了一个补丁,我还没有成功实现。一旦我能确认补丁修复了行为,我将发布它。