sed 中的反转匹配打印所有行直到换行

sed 中的反转匹配打印所有行直到换行

我需要在段落中打印反向匹配(反向匹配模式将位于段落的第一行和单词末尾),直到换行。

尝试sed使用[^text]不起作用。

我的模式字符串将位于 word 的末尾xxx_yyyy: ZZZ

sed -n '/[^ZZZ]$/,/^$/p'不工作。

有人可以纠正我这里出了什么问题吗?

输入:

sometext tobe here xxx_yyyy: ZZZ
sjhdajsh 
skdjah
hjk 

sometext tobe here xxx_yyyy: AAA 
sjhdajsh 
skdjah 
hjk 

sometext tobe here xxx_yyyy: ZZZ
sjhdajsh
skdjah 
hjk

期望的输出:

需要打印不包含的段落xxx_yyyy: ZZZ

sometext tobe here xxx_yyyy: AAA
sjhdajsh 
skdjah 
hjk

答案1

awk这比使用更容易做到sed

$ awk -v RS='' -F '\n' '!($1 ~ /ZZZ$/)' file
sometext tobe here xxx_yyyy: AAA
sjhdajsh
skdjah
hjk

首先将记录分隔符 , 设置RS为空字符串。使用这个特殊值RS,awk会将由一个或多个空行分隔的每个段落视为一条记录。我们-F '\n'告诉awk将段落的每一行视为一个字段。

!($1 ~ /ZZZ$/)对于第一个字段(第一行)符合以下条件的每条记录(段落),测试结果均为真:不是以字符串结尾ZZZ。每个这样的段落都将被打印。

如果您希望每个输出部分后有一个空行,请添加-v ORS='\n\n'awk命令行(代码之前awk)。


有了sed,你可以做

$ sed '/ZZZ$/,/^$/d' file
sometext tobe here xxx_yyyy: AAA
sjhdajsh
skdjah
hjk

即,“删除以任何行结尾ZZZ到下一个空行之间的所有行”。您还可以将sed表达式/ZZZ$/,/^$/!p与 一起使用sed -n。但请注意,ZZZ任何其他段落第一行以外的行也会触发此删除。

这个问题显然可以解决(通过逐行阅读段落,进入保留空间,然后决定打印哪些内容以及丢弃哪些内容),但它会比仅仅使用awk上面的变体更麻烦。


只是评论[^ZZZ]您在问题中使用的表达方式。这完全等同于[^Z]并且将匹配任何不是 的单个字符Z。同样,与、或 以外的任何单个字符[^text]相同,并且会匹配。[^etx]etx

相关内容