【问题标题】:Linux ubuntu Awk. Find the sentences containg 2 same words placed near themselvesLinux ubuntu awk。找到包含 2 个相同单词的句子,它们放在它们附近
【发布时间】:2016-05-19 11:57:30
【问题描述】:

我想打印包含两个相同单词的所有句子。 句子以 结尾。或者 ?或!。

对于输入:

word ja ba word. Na Na word wdd? Nothing kkk
ok ok! word no this no word. ok ok. notok!

输出应该是:

Na Na word wdd?

Nothing kkk
ok ok!

ok ok.

这是我目前的代码:

 #!/bin/bash
if [ $# -eq 0 ]
 then
echo "No arguments"
 fi

if [[ -f $1 ]] #if its file
then

cat $1 | awk '{
for (i=1;i<=NF;i++)         
  {

}}'

fi

我不知道如何用 AWK 分隔完整的句子。我不能使用多文件分隔符(!它很重要)。如果我将它们分开,如何检查里面的每个单词?我需要使用 AWK。

这是我的最新想法:

cat $1 | awk  '{
 for (i=1;i<=NF;i++)         
  {
   a=0;
    if ($i ~ "\?$" || $i ~ "\!$" || $i ~ "\.$")          
    {

  #print $i;
      k='';

    for(j=$i; j!=$a; j--);
    {
      if( $j == $k)
        #print whole sentence

       $k=$j;

    }

    }
}}'

我找到了以?/./!结尾的单词,然后检查最后一句之前的所有单词

【问题讨论】:

  • 为什么Nothing kkk 会出现在输出中?它不应该
  • 中间有换行符(\n),句尾只有./?/!
  • 当你说你必须使用AWK时,你的意思是你没有(或不能使用)gawk吗?因为使用 gawk 您可以使用正则表达式作为记录分隔符 gawk -v RS='[!?.]' ...

标签: linux bash awk


【解决方案1】:

grep 就足够了:

grep -Pzo "[^.?!]*\b(\w+) \1[^.?!]*"

测试:

$ echo '''word ja ba word. Na Na word wdd? Nothing kkk  
ok ok! word no this no word. ok ok. notok!''' | grep -Pzo "[^.?!]*\b(\w+) \1[^.?!]*"  
Na Na word wdd  
Nothing kkk  
ok ok  
ok ok

解释:

  • -o 标志使grep 只返回匹配的结果,而不是它出现的行
  • -P 标志使grep 使用 PCRE 正则表达式
  • -z 标志在行尾抑制换行符,用它代替 nul 字符。也就是说,grep 知道行尾在哪里,但会将输入视为一条大行。
  • [^.?!]* 匹配句子的开头:它将匹配尽可能多的字符,但不匹配句子终止符 (.?!)
  • \b(\w+) 匹配单词字符,并将它们分组到正则表达式的第一组。单词边界确保我们不仅匹配单词的结尾(感谢 123 !)。
  • \1 引用了第一组,所以我们必须有两个相同的单词,用空格隔开
  • [^.?!]* 匹配句尾

【讨论】:

  • cat $1 | grep -Pzo "[^.?!]*(\w+) \1[^.?!]*" 对我不起作用(我使用的是 Ubuntu)
  • 没关系。我选择了错误的文本文件作为 arg。效果很好。你能用awk做吗?无论如何,干得好,谢谢!
  • 我对@9​​87654334@不够熟悉,我通常用grepsed解决我所有的任务。您显然可以等待awk 回答接受,我将把这个留在这里,以防遇到同样问题的人没有您的工具限制:)
  • 顺便说一句,grep &lt;pattern&gt; &lt;file&gt;cat &lt;file&gt; | grep &lt;pattern&gt; 的更清洁(并且可能更有效)的替代品 :)
  • 这将匹配诸如wow ow之类的句子,您需要在第一个匹配之前使用分隔符。 "[^.?!]*\b(\w+) \1[^.?!]*"
【解决方案2】:

gawk

$ awk -v RS='[!?.] +' '{for(i=1;i<NF;i++) if($i==$(i+1)) print $0 RT "\n"}' file

Na Na word wdd?

Nothing kkk
ok ok!

ok ok.

设置以[!?.] 和可选空格结尾的记录。遍历句子中的单词进行重复,打印带有匹配记录终止符的句子和句子之间的换行符。

这里是和这里文档相同的脚本

awk -v RS='[!?.] +' '{for(i=1;i<NF;i++) if($i==$(i+1)) print $0 RT "\n"}' << EOF
> word ja ba word. Na Na word wdd? Nothing kkk
> ok ok! word no this no word. ok ok. notok!
> EOF

应该给你

Na Na word wdd?

Nothing kkk
ok ok!

ok ok.

【讨论】:

  • 它不会为我打印Nothing kkk ok ok
  • 你的awk --version是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
相关资源
最近更新 更多