sed如果范围中包含其他模式,则从该范围中删除行

时间:2018-07-24 01:31:37

标签: bash awk sed

仅当范围包含第二个图案时,才如何从范围中删除某些包含图案的行?

例如:

## start
  ## first line
    ## 2nd pattern
      ## third line
# end

范围是从## start# end,但是我只想删除其中带有##的行。

我使用了sed "/## start/,/# end/ {/##/ d}命令。

当我只想删除这些行中的2nd pattern时出现问题。因此

## start
  ## first line
    ## second line
# end

不应删除。但是,它将被我拥有的命令删除。

##可以有多行(不仅是我显示的4个级别),而且它们将始终在一起。

编辑:

## start
  ## first line
    ## adsg
      ## third line
# end
## start
  ## first line
    ## 2nd pattern
      ## second line
# end

应提供

## start
  ## first line
    ## adsg
      ## third line
# end
# end

3 个答案:

答案 0 :(得分:0)

您可以尝试以下脚本replace.awk

#!/bin/awk -f

BEGIN{f=0; inblock=0}
/## start/{inblock=1}
inblock && /# end/{
    if(!f){
        for (k in m){
            mm[k] = m[k];
        }
    }
    for (k in m){
        delete m[k];
    }
    inblock = 0; 
}
inblock{m[NR]=$0;}
!inblock{mm[NR]=$0;}
inblock && /## 2nd pattern/ {f = 1;} 
END{ 
    for (k in mm){
        print mm[k]
    }
}

显然,您需要授予执行权限,chmod +x replace.awk

最后,要运行脚本,请使用:./replace.awk file

答案 1 :(得分:0)

您需要将2nd模式添加到删除表达式中,例如

$ sed '/## start/,/# end/{/##.*2nd/d}' file
## start
  ## first line
      ## third line
# end

如果您想保留其他行中带有'2nd\ pattern'的行,则可以添加完整的2nd以进一步指定确切的词组。

如果我误解了,请在下面发表评论。

答案 2 :(得分:0)

这可能对您有用(GNU sed):

sed '/^## start/{:a;N;/^# end/M!ba;/2nd pattern/!b;s/^.*##.*\n//Mg}' file

这会收集## start# end之间的行,除非集合中包含第二个模式,否则它们会自动退出。如果进行匹配,则会删除集合中包含##的行。

M标志允许多行正则表达式。在这些情况下,元字符^$充当行首和行尾的标记。