【问题标题】:Regex match as many of strings as possible正则表达式匹配尽可能多的字符串
【发布时间】:2015-07-11 21:04:14
【问题描述】:

我不知道这是否可行或有意义,但我想做的是grepawk 匹配多个字符串的文件,但只显示匹配最多字符串的匹配项。

所以我会有一个类似的文件:

cat,dog,apple,bark,chair
apple,chair,wall
cat,wall
phone,key,bark,nut
cat,dog,key
phone,dog,key
table,key,chair

我想匹配包含大部分这些字符串的单行:cat|dog|table|key|wall。不一定要包括所有这些,但是任何最匹配的行,打印它。

例如,我希望它显示以下输出:

cat,dog,key

因为它是包含正在搜索的大部分字符串的行。

我尝试过使用:

cat filename \
|egrep -iE 'cat' \
|egrep -iE 'dog' \
|egrep -iE 'table' \
|egrep -iE 'key' \
|egrep -iE 'wall'

但它只会显示显示所有字符串的行,我也尝试过:

egrep -iE 'cat|dog|table|key|wall' filename

但这显示了与这些字符串中的任何一个匹配的任何行。

正则表达式可以做这样的事情吗?

【问题讨论】:

  • 这不可能使用正则表达式,但您可以编写一个简单的 AWK 脚本来做到这一点。
  • cat 匹配 catch

标签: regex string awk grep


【解决方案1】:

使用awk,并为每个匹配的单词增加一个计数器。如果计数器高于最高计数,则保存此行。

awk 'BEGIN {max = 0}
     { count=0;
       if (/\bcat\b/) count++;
       if (/\bdog\b/) count++;
       ...
       if (count > max) { saved = $0; max = count; }
     }
    END { print saved; }'

【讨论】:

  • 您可以在BEGIN 块中分配它
  • 它实际上在最后添加,我只是忘记将它与 ' 隔开,再次感谢您的帮助!
【解决方案2】:
$ awk -F, -v r='^(cat|dog|table|key|wall)$' '{c=0;for (i=1;i<=NF;i++)if ($i~r)c++; if (c>max){max=c;most=$0}} END{print most}' file
cat,dog,key

工作原理

  • -F,

    这会将字段分隔符设置为逗号。

  • -v r='^(cat|dog|table|key|wall)$'

    这会将变量 r 设置为匹配您感兴趣的单词的正则表达式。正则表达式以^ 开头,以$ 结尾。 这确保只有整个单词匹配。

  • c=0;for (i=1;i&lt;=NF;i++)if ($i~r)c++

    这会将变量c 设置为当前行的匹配数。

  • if (c&gt;max){max=c;most=$0}

    如果当前行上的匹配数 c 超过了之前的最大值 max,则更新 max 并将 most 设置为当前行。

  • END{print most}

    当我们读完文件后,打印带有most 匹配的行。

【讨论】:

  • 这也行得通!谢谢你的解释!你摇滚!
  • 不错的解决方案。如果一个单词重复,我们的两种解决方案会有所不同:我的算一次,这个算一次。
【解决方案3】:

为了让问题更有趣,我创建了两个输入文件:

InFile1 ...

cat|dog|table|key|wall

InFile2 ...

cat,dog,apple,bark,chair
apple,chair,wall
cat,wall phone,key,bark,nut
cat,dog,key
phone,dog,key
table,key,chair

请注意,InFile2 与原始帖子不同 因为它包含两行,每行有三个匹配项。 因此,第一名有一个“领带”,两者都是 报告。

这段代码...

 awk -F, '{if (NR==FNR) r=$0; else {count=0
   for (j=1;j<=NF;j++) if ($j ~ r) count++
   a[FNR]=count" matching words in "$0
   if (max<count) max=count}}                     
   END{for (j=1;j<=FNR;j++) if (1==index(a[j],max)) print a[j]}'  \
$InFile1 $InFile2 >$OutFile

... 生成了这个 OutFile ...

3 matching words in cat,dog,key
3 matching words in table,key,dog,banana

丹尼尔·B·马丁

【讨论】:

    猜你喜欢
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 2012-06-05
    • 2013-12-25
    相关资源
    最近更新 更多