如何grep 2到4次出现的任何单词?

时间:2016-12-12 13:32:41

标签: regex bash unix grep

我的档案是:

ab  12ab 1cd uu 88 ab 33 33 1 1
ab cd uu  88 88  33 33 33 cw ab

我需要提取出现2-4次的单词和数字.- {2,4} 我尝试过很多正则表达式,甚至是regex101。 我真的无法理解什么不起作用。

这是我到目前为止最接近的:

egrep -o '[\w]{2,4}' A1

5 个答案:

答案 0 :(得分:1)

原生grep不会支持\w{}符号。你必须使用扩展的正则表达式。

使用

-E选项为,

  

-E, - extended-regexp                将模式解释为扩展正则表达式(即强制grep表现为egrep)。

也可以使用

-w匹配单词,以便匹配整个单词而不是部分单词。

  

-w, - word-regexp                搜索表达式为单词(好像被[[:<:]]' and [[:&gt;:]]'包围;请参阅re_format(7))。

示例

$ grep -Ewo "\w{2,4}" file
ab
12ab
1cd
uu
88
ab
33
33
ab
cd
uu
88
88
33
33
33
cw

注意

您可以通过提供cat作为file的输入来取消使用不必要的grep

答案 1 :(得分:0)

你很亲密;在字符类符号[]中,特殊符号\w按字面意思处理,从[]中删除:

egrep -o '\w{2,4}'

同样egrep不赞成使用grep -E,并且您不需要cat作为grep将文件作为参数:

grep -Eo '\w{2,4}' file.txt

答案 2 :(得分:0)

我会使用awk:

awk '{for(i=1;i<=NF;i++)a[$i]++}
     END{for(x in a)if(a[x]>1&&a[x]<5)print x}' file

它会扫描整个文件,找出此范围内出现的字词(在文件中)[2,4]

输出是:

uu
ab
88
1

答案 3 :(得分:0)

使用AWK,此解决方案计算每行不是每个文件的单词实例:

awk '{delete array; for(i = 1; i <= NF; i++) array[$i]+=1; for(i in array) if(array[i] >= 2 && array[i] <= 4) printf "%s ", i; printf "\n" }' input.txt

删除以清除每个新行的数组。使用字段作为数组索引的哈希值,并将其值增加1。使用介于2和4之间的值打印索引(字段)。

输出:

ab 1 33 
ab 88 33 

答案 4 :(得分:0)

Perl实现的文件足够小,可以将其内容作为单个字符串处理:

$/ = undef;
$_ = <>;
@_ = /(\b\w+\b)/gs;

my %h; $h{$_}++ for @_;

for (keys %h) {
  print "$_\n" if $h{$_} >= 2 and $h{$_} <= 4;
}

将其保存到script.pl并运行:

perl script.pl < file

当然,您也可以通过-e选项传递代码:perl -e 'the code' < file

输入

ab  12ab 1cd uu 88 ab 33 33 1 1
ab cd uu  88 88  33 33 33 cw ab

输出

88
uu
ab
1

输出中没有33,因为它在输入中出现了5次。

代码将slurp mode中的文件读入默认变量($_),然后收集所有带有字边界的\w)到@_数组。然后它计算文件中每个单词出现的次数,并将结果存储到%h哈希中。最后一个块仅打印出2,3或4次,不多也不少的项目。

注意,在Perl中,您应始终use strict;use warnings;以便在早期阶段发现问题。