如何解决使用sed删除模式b以后的所有从模式b开始的行
给出如下文件:
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 的连续一行。
解决方法
对于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
的下一行读入模式空间 -
s/\n[[:blank:]]*-.*//
-查找并删除换行符,0 +个空白字符,-
和其余字符串 -
ta
-如果发生替换,sed
会转到标记为a
的位置 -
!P
-否则,打印模式空间内容,直到第一行(换句话说,打印第一行) -
D
-删除模式空间的内容,直到第一行,即删除模式空间内的第一行,然后使用结果模式空间重新开始循环,而无需读取新的输入行。
-
尽管yaml文件应该由能够理解它们的工具来解析,因为OP已使用sed
,所以我在这里提出了awk
解决方案。您可以尝试以下吗?在链接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
的行时,形成一个获取下一行的循环,如果该行以一些空格开头,后跟-
,则重复该循环。
否则,打印所有其他行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。