得到文本正文中的最后一个单词

时间:2015-06-22 20:40:47

标签: regex awk sed grep

鉴于文本正文可以跨越不同数量的行,我需要使用解决方案来搜索相同模式的许多文件,得到身体的最后一句话。

文件可以包含这样的格式,其中我想要的单词可以命名为

call function1(input1,  
               input2,    #comment  
               input3)    #comment  
               returning randomname1,    
             randomname2,  
                 success3

call function1(input1,
               input2,    
               input3)    
               returning randomname3, 
randomname2, 
randomname3


call function1(input1,
               input2,    
               input3)   
               returning anothername3, 
randomname2, anothername3

我需要打印出结果

success3
   randomname3
   anothername3

另外,我需要一些关于每个的文件名和行信息。

我试过

pcregrep -M 'function1.*(\s*.*){6}(\w+)$' filename.txt

这太贪心了,我仍然需要打印出特定的分组值,而不是整个模式。在我的示例代码中返回的单词function1将始终以此命名,并且可以在我的表达式中进行硬编码。

4 个答案:

答案 0 :(得分:5)

代码块的最后一句话

使用的记录分隔符RS在块中拆分文件。记录将被定义为文本块,记录由双新行分隔。

记录由字段组成,每两个连续字段由空格或单个换行符分隔。

现在我们要做的就是打印每条记录的最后一个字段,产生以下代码:

awk 'BEGIN{ FS="[\n\t ]"; RS="\n\n"} { print $NF }' file

说明:

  • FS这是字段分隔符,设置为换行符,制表符或空格:[\n\t ]
  • RS这是记录分隔符,设置为doulbe换行符:\n\n
  • print $NF这将打印带有索引$的字段NF,该字段是包含字段数的变量。因此,这将打印最后一个字段。

注意:要捕获文件应以双换行结尾的所有段落,可以使用以下方法预处理文件轻松实现:$ echo -e '\n\n' >> file

基于评论的替代解决方案

更优雅的简单解决方案如下:

awk -v RS='' '{ print $NF }' file

答案 1 :(得分:3)

以下awk解决方案如何:

awk 'NF == 0 {if(last) print last; last=""} NF > 0 {last=$NF} END {print last}' file

$NF获取最后一个"字"的值其中NF代表字段数。然后last变量总是将最后一个单词存储在一行上,如果它遇到一个空行,则打印出来,表示段落的结尾。

匹配function1条件的新版本。

awk 'NF == 0 {if(last && hasF) print last; last=hasF=""}
  NF > 0 {last=$NF; if(/function1/)hasF=1}
  END {if(hasF) print last}' filename.txt

答案 2 :(得分:2)

这将生成您从发布的输入文件中显示的输出:

$ awk -v RS= '{print $NF}' file
success3
randomname3
anothername3

如果你想像你提到的那样打印FILENAME和行号,那么这可能是你想要的:

$ cat tst.awk
NF { nr=NR; last=$NF; next }
{ prt() }
END { prt() }
function prt() { if (nr) print FILENAME, nr, last; nr=0 }

$ awk -f tst.awk file
file 6 success3
file 13 randomname3
file 20 anothername3

如果这样做不符合您的要求,请编辑您的问题,以提供更清晰,更真实的代表性和准确的样本输入和预期输出。

答案 3 :(得分:1)

这是贝类的awk解决方案的perl版本(加上关键字):

perl -00 -nE '/function1/ and /returning/ and say ((split)[-1])' file

或者,有一个正则表达式:

perl -00 -nE '/^(?=.*function1)(?=.*returning).*?(\S+)\s*$/s and say $1' file

但关键是-00选项,它一次读取一个段落。