使用 sed 删除模式 a 行之后以模式 b 开头的所有行

Use sed to delete all lines starting with pattern b after line with pattern a

给定如下文件:

first line
second line DELETE ME
  - third line
  - fourth line
fifth line
sixth line DELETE ME
seventh line
  - eighth line

以及模式 a (DELETE ME) 和模式 b ([[:blank:]]*-),我会只喜欢保留

first line
fifth line
seventh line
  - eighth line

或者换句话说,我想删除包含模式 a 的每一行以及所有 直接跟随 开头的行模式 b.

到目前为止,我只满足了一些但不是全部的要求:

sed '/DELETE ME/{N;s/^[[:blank:]]*-//;d;}'

这应该删除包含 a 的所有行以及包含 b.

的一个连续行

虽然 yaml 文件应该由理解它们的工具来解析,因为 OP 使用了 sed 所以我在这里提供了一个 awk 解决方案。能否请您尝试以下。在 link https://ideone.com/WNROOt 中编写和测试,并且仅使用所示样本进行测试和编写。

awk '
!/^ +/{
  foundDel=""
}
/DELETE ME/{
  foundDel=1
  next
}
foundDel && /^ +/{
  next
}
1
' Input_file

注意:如果您想将输出保存到 Input_file 本身,然后附加 > temp && mv temp Input_file

这可能适合您 (GNU sed):

sed -n '/DELETE ME/{:a;n;/^\s*-/ba};p' file

通过设置选项 -n 关闭隐式打印。

遇到包含 DELETE ME 的行时,形成一个循环来获取下一行,如果该行以一些空格开头后跟 -,则重复循环。

否则,打印所有其他行。

使用 GNU sed,您可以使用

sed '/DELETE ME/{:a;N;s/\n[[:blank:]]*-.*//;ta;!P;D}' file

参见 online sed demo:

s='first line
second line DELETE ME
  - third line
  - fourth line
fifth line
sixth line DELETE ME
seventh line
  - eighth line'
sed '/DELETE ME/{:a;N;s/\n[[:blank:]]*-.*//;ta;!P;D}' <<< "$s"

输出:

first line
fifth line
seventh line
  - eighth line

详情

  • /DELETE ME/ - 查找包含 DELETE ME 字符串
  • 的所有行
  • {:a;N;s/\n[[:blank:]]*-.*//;ta;!P;D} - 如果找到匹配 DELETE ME 的行,则进入此块:
    • :a - a 标签标记当前位置
    • N - 将开头为 \n 的下一行读入模式 space
    • s/\n[[:blank:]]*-.*// - 查找并删除换行符、0+ 个空白字符、- 和字符串的其余部分
    • ta - 如果发生替换,sed 会转到标有 a
    • 的位置
    • !P - 否则,打印模式 space 内容直到第一个换行符(即打印第一行)
    • D - 删除模式 space 内容直到第一个新行,即删除模式 space 内的第一行,并使用结果模式 space 重新开始循环], 没有读取新的输入行。