sed n不';I don’’看来它不像我想象的那样工作

sed n不';I don’’看来它不像我想象的那样工作,sed,Sed,我试图复制我在这里找到的一个例子: 这里是sed模式 /^begin$/,/^end$/{ /begin/n /end/!d } 这是第一个文件 begin one end last line $ sed -f x.sed a begin end last line 这是第二个 begin end last line 当我在第一个文件上运行sed时,它会删除begin/end和all is well之间的内容。当我在第二个服务器上运行它时,它似乎错过了“end”并删除了文

我试图复制我在这里找到的一个例子:

这里是sed模式

/^begin$/,/^end$/{
    /begin/n
    /end/!d
}
这是第一个文件

begin
one
end
last line
$ sed -f x.sed a
begin
end
last line
这是第二个

begin
end
last line
当我在第一个文件上运行sed时,它会删除begin/end和all is well之间的内容。当我在第二个服务器上运行它时,它似乎错过了“end”并删除了文件的其余部分

在第一个文件上运行

begin
one
end
last line
$ sed -f x.sed a
begin
end
last line
跑在第二位

$ sed -f x.sed b
begin
end
注意第二次运行时“最后一行”是如何丢失的

我以为“n”会打印当前的图案,然后吸进下一个图案。然后它将点击/end/命令并处理该问题

事实上,它似乎以某种方式导致错过了射程的终点。有人能解释一下发生了什么吗?

应该是:

/^begin$/,/^end$/{
    /^begin$\|^end$/!d
}

为什么你的命令错了

那里的
n
命令错误。在第二个示例中,它将:

  • begin
    -->n读取下一行(重要提示:这不会影响范围地址的状态(begin,end))

    1a<代码>结束-->
    /end/不适用。不要删除该行

  • 最后一行
    -->
    /end/适用。删除该行。(
    sed
    仍在搜索包含
    end
    的行,因为
    n
    命令跳过了该行)


  • 在@hek2mgl的帮助下找到了另一种方法。我可以在第二条语句周围添加分支。我确实需要这个,因为我想看看begin标签。所以你也可以这样做:

    /^begin$/,/^end$/{
    /begin/{ b skip }
    /end/!d
    :skip
    

    }

    我想你已经接近让它做你想做的了。当您想在匹配后删除下一行时,只需使用sed
    n
    将其拉入,然后用delete
    d
    点击即可

    看起来您希望跳过以
    begin
    开头的行之后的行,除非它是
    end
    并打印所有其他行

    如果是这样,以下内容就足够了:

    /^begin$/,/^end$/{
    /begin/{n;/end/!d}
    }
    
    它的工作原理是跳过begin之后的下一行,除非它以end开头(
    /end/!


    另请参见:

    可能没有帮助:如果可以使用awk,它会变得更可靠:
    awk-vp=1'/^end$/{p=1};p/^开始$/{p=0}'文件
    你能解释一下它在那里做了什么吗?我可以看出它不起作用,但感觉应该起作用。补充说明。我希望它能帮上忙。所以它在循环中读两行,然后跳过范围检查?