我的档案是:
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
答案 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;
以便在早期阶段发现问题。