sed:删除上一行

Bub*_*off 4 regex sed

我需要在比赛前删除一个空行.

所以给定文件:

random text
more random text






#matchee
Run Code Online (Sandbox Code Playgroud)

我需要匹配模式/ #matchee /,然后删除之前的空白行.

这是我尝试过的 - 没有成功:

sed '/^[ \t]*$/{N;/#matchee.*$/{D;}}' file.txt
Run Code Online (Sandbox Code Playgroud)

我的逻辑:

  • 如果是空行; 将下一行追加到模式空间中产生/空行\n ...等/
  • 如果模式空间包含/ #matchee /,则删除到换行符/ #matchee /

基本上/ matchee /是一个必须维护的常量,我需要从/ #matchee /分隔的记录文件中的每个记录中删除一个额外的空行.

无论什么都没有效果.我是RTFM-ing并且D 应该删除模式空间直到换行符.因为N添加换行符加下一行 - 这应该产生预期的结果....唉......不,不再.这是因为匹配基本上没有(空白)吗?

rua*_*akh 5

如果存在奇数个空行,您的方法将起作用,但如果存在偶数,则它将失败.您的sed脚本是以下循环.

  • 抓住一条线L1,并将其添加到图案空间
  • 如果L1非空白,则打印出来; 但如果空白,那么:
    • 抓住另一条线L2,并将其添加到模式空间
    • 如果L2包含#matchee,则从模式空间中丢弃L1
    • 打印模式空间,它由L1L2组成,或仅由L2组成

您会注意到L2始终打印,即使它是空白的,后面跟着一行#matchee.它受到以下事实的保护:它紧跟着奇数个空行.

编辑添加:要修复上述问题,可以使用:命令创建标签和b"分支"到它(goto)的命令来添加内部循环.这个:

sed '/^[ \t]*$/{: a;N;/#matchee/!P;D;/^[ \t]*$/b a}' file.txt
Run Code Online (Sandbox Code Playgroud)

是以下循环:

  • 抓住一条线L1,并将其添加到图案空间
  • 如果L1非空白,则打印出来; 但如果空白,那么:
    • 创建标签a←这是一个无操作,只是一个地方goto
    • 抓住另一条线L2,并将其添加到模式空间
    • 如果L2包含#matchee,打印L1
    • 丢弃图案空间中的L1(无论我们是否打印出来)
    • 我们现在可以将L2视为L1 ; 它是模式空间中唯一的东西
    • 如果重新命名的L1是空白的,goto a