2016-03-07 56 views
1

对于给定的文本文件,我想将每个句子中的最后一个单词提取为空格分隔的文本文件。对于像Mr.和Dr.这样的词语有一些错误是可以接受的,所以我不需要尝试达到那种精确度。如何提取句子的最后一个单词

我在想我可以用Sed和Awk做到这一点,但是我和他们合作已经太久了,我不记得从哪里开始。帮帮我?

(输出例如:对于前面两个段落,我希望看到这一点):

file Mr Dr precision begin Help 
+0

欢迎来到StackOverflow!但是..哎呀,你忘了发布你的代码。 StackOverflow是关于帮助人们修复他们的代码。这不是免费的编码服务。任何代码都比没有代码更好。即使你不知道如何编写代码本身,元代码甚至也会演示你如何思考问题。请查看http://stackoverflow.com/help/how-to-ask获取有关改善此问题的提示。 – ghoti

回答

2

使用这个表达式:

([[:alpha:]]+)[.!?] 

Explanation

grep的可以这样做:如果你只想要的话

$ echo "$txt" | grep -o -E '([[:alpha:]]+)[.!?]' 
file. 
Mr. 
Dr. 
precision. 
begin. 
Help? 

然后,通过第二次:

$ echo "$txt" | grep -o -E '([[:alpha:]]+)[.!?]' | grep -o -E '[[:alpha:]]+' 
file 
Mr 
Dr 
precision 
begin 
Help 

在awk中,相同的正则表达式:

$ echo "$txt" | awk '/[[:alpha:]]+[.!?]/{for(i=1;i<=NF;i++) if($i~/[[:alpha:]]+[.!?]/) print $i}' 

Perl中,相同的正则表达式,可以捕捉组,也许一点点更直接的语法:

$ echo "$txt" | perl -ne 'print "$1 " while /([[:alpha:]]+)[.!?]/g' 
file Mr Dr precision begin Help 

而且用Perl,它更容易refine the regex是有关的话更多的歧视捕获:

echo "$txt" | perl -ne 'print "$1 " while /([[:alpha:]]+)(?=[.!?](?:(?:\s+[[:upper:]])|(?:\s*\z)))/g' 
file precision begin Help 
+0

感谢您的支持!我尝试了各种建议,但这是最有用的,我从中学到了最多。 Perl真的让我歧视! – Madroaster

0

容易在Perl:

perl -ne 'print "$1 " while /(\w+)[.!?]/g' 
  • -n由线读取输入线。
  • \w匹配“单词字符”。
  • \w+匹配一个或多个单词字符。
  • [.!?]匹配任何句末标记。
  • /g代表“全局” - 它记住最后一场比赛发生在哪里,并在比赛结束后尝试匹配。
2

GAWK:

$ gawk -v ORS=' ' -v RS='[.?!]' '{print $NF}' w.txt 
file Mr Dr precision begin Help 

(请注意,纯awk不支持将正则表达式分配给RS。)

1

这可能会为你工作(GNU SED):

sed -r 's/^[^.?!]*\b(\w+)[.?!]/\1\n/;/\n/!d;P;D' file 

对于每行一个字或使用膏一行这样:

sed -r 's/^[^.?!]*\b(\w+)[.?!]/\1\n/;/\n/!d;P;D' file | paste -sd' ' 

另一种解决方案仅仅使用SED:

sed -r 'H;$!d;x;s/\n//g;s/\b(\w+)[.?!]/\n\1\n/g;/\n/!d;s/[^\n]*\n([^\n]*)\n/ \1/g;s/.//' file 
相关问题