使用 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 重新开始循环], 没有读取新的输入行。
给定如下文件:
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
的下一行读入模式 spaces/\n[[:blank:]]*-.*//
- 查找并删除换行符、0+ 个空白字符、-
和字符串的其余部分ta
- 如果发生替换,sed
会转到标有a
的位置
!P
- 否则,打印模式 space 内容直到第一个换行符(即打印第一行)D
- 删除模式 space 内容直到第一个新行,即删除模式 space 内的第一行,并使用结果模式 space 重新开始循环], 没有读取新的输入行。