我需要在段落中打印反向匹配(反向匹配模式将位于段落的第一行和单词末尾),直到换行。
尝试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]
e
t
x