如何使用awk打印最后的图案范围?
我的文件如下: /开始模式/如何使用awk打印最后的图案范围?,awk,Awk,我的文件如下: /开始模式/第一次匹配 /结束模式/ 其他文本 /开始模式/第二次匹配 /结束模式/ 其他文本 /开始模式/这是我想要的模式 要打印出来吗/end 模式/其他文本 如何使用awk打印最后一个匹配?我只知道如何打印所有这些匹配项。存储当前匹配项并使用结束块打印: awk '/end pattern/{flag=0} flag{m=$0} /begin pattern/{flag =1} END{print m}' file 如果在/begin pattern/和/end pat
第一次匹配
/结束模式/
其他文本
/开始模式/
第二次匹配
/结束模式/
其他文本
/开始模式/
这是我想要的模式 要打印出来吗
/end 模式/
其他文本
如何使用awk打印最后一个匹配?我只知道如何打印所有这些匹配项。存储当前匹配项并使用结束块打印:
awk '/end pattern/{flag=0} flag{m=$0} /begin pattern/{flag =1} END{print m}' file
如果在/begin pattern/和/end pattern/之间只有一行,则此操作有效,具体取决于是否要打印包含分隔符的行:
awk 'END { print r }
/end pattern/ { f = x }
/begin pattern/ { f = 1; r = x }
f++ > 1 { r = r ? r RS $0 : $0 }
' infile
$ awk '
/begin pattern/ { rec=""; f=1 }
f { rec=rec $0 ORS; if (/end pattern/) {last=rec; f=0} }
END { printf "%s", last }
' file
/begin pattern/
This is the one I want to print out
/end pattern/
或:
这确保了打印的是一个以
begin pattern
开始、以end pattern
结束的块,因此,如果在输入文件的末尾存在start pattern
之后,您不必只打印一堆行,而不打印任何end pattern
。它还可以确保在输入中不存在匹配块的情况下不打印空行。使用x
的方式很有趣。在/end模式/
中,它实际上是0
;在/begin模式/
中,它实际上是“
(空字符串)。它从来没有设置为任何东西。在我看来,使用0
和“
会更清晰。它当然会起作用,但在脚本的开头看到END语句而不是在脚本的结尾,这很奇怪。此外,我盯着这个问题看了很久,试图找出r
和x
之间的区别,然后才意识到您正在使用未设置变量x
作为空字符串!不要把你的代码弄糊涂了,因为为了节省输入更多的字符-f
是一个数字,r
是一个字符串,而不是用一个未设置的变量x
和r=x
,只要使用f=0
和r=”“
就可以了。现在我明白代码在做什么了,它会失败的(跳过它们)当begin pattern
之后的第一行为0
或为空时。当不存在end pattern
时,它还会在文件末尾打印begin pattern
之后的任何行,而不是打印begin pattern
和end pattern
之间的最后一组行,并打印一个空行如果输入中不存在匹配的块。@埃德蒙顿:这很微妙。r=r?r$0:$0
如果前面的行包含0
(或00
或0.0
或“0
”等),或者如果它是空的(但如果该行只包含空白的话,则不计算r
,则计算为“false”)。修复此问题需要更多的工程工作。f++>1
条件确保忽略开始模式行。使用f
或f==1
将在输出中包含开始模式。要在输出中包含结束模式,必须在结束模式操作中将$0
添加到r
。@JonathanLeffler这种“在一个范围内打印文本”的东西是比听起来要复杂得多的东西之一。我们甚至没有涉及到部分匹配、全行匹配、全词匹配、字符串与regexp匹配,以及开始和结束字符串可能出现在同一行或中间行的情况。很容易想出一个“解决方案”这适用于已发布的示例输入集,然后在6个月后在实际客户数据上运行时崩溃!如果您使用awk'/begin pattern/,/end pattern/,
,并且在末尾附近有一个begin pattern,后面没有结束模式,那么该材料将被打印出来。问题并没有解决发生这种情况时所需的内容-这将是r请看第二个输入示例。您记录了您认为“不完整块”是不可打印的内容-是否值得记录在打印不完整块时该怎么做?我认为它变成了END{if(f)last=rec;printf“%s”,last}
,不是吗?至少对于“无定界符”代码来说是这样。我从不使用范围表达式,因为它们会为琐碎的问题保存几个字符,然后在问题变得稍微有趣时需要完全重写或复制条件,所以在我的心目中,它们根本不值得麻烦。如果一个不完整的bl我想你根本没有last
变量,只需要打印rec
。啊-是的,你不使用last
而只是打印rec
可能是对的。
$ awk '
f { if (/end pattern/) {last=rec; f=0} rec=rec $0 ORS }
/begin pattern/ { rec=""; f=1 }
END { printf "%s", last }
' file
This is the one I want to print out