我想找到包含任意单词三次的行。为此,我认为最好使用该grep
命令。
这是我的尝试。
grep '\(.*\)\{3\}' myfile.txt
答案1
使用标准词定义,
GNU 格雷普,3个或更多的出现次数任何单词。
grep -E '(\W|^)(\w+)\W(.*\<\2\>){2}' file
GNU 格雷普,只有3个的出现次数任何单词。
grep -E '(\W|^)(\w+)\W(.*\<\2\>){2}' file | grep -Ev '(\W|^)(\w+)\W(.*\<\2\>){3}'
POSIX awk,只有3个的出现任何单词。
awk -F '[^_[:alnum:]]+' '{ # Field separator is non-word sequences split("", cnt) # Delete array cnt for (i=1; i<=NF; i++) cnt[$i]++ # Count number of occurrences of each word for (i in cnt) { if (cnt[i]==3) { # If a word appears exactly 3 times print # Print the line break } } }' file
为了3个或更多发生时,只需更改
==
为>=
.等效高尔夫球单线:
awk -F '[^_[:alnum:]]+' '{split("",c);for(i=1;i<=NF;i++)c[$i]++;for(i in c)if(c[i]==3){print;next;}}' file
GNU Awk,仅出现 3 次单词
ab
。gawk 'gsub(/\<ab\>/,"&")==3' file
为了3个或更多发生时,只需更改
==
为>=
.
阅读材料
\2
是一个反向引用。\w
\W
\<
\>
GNU Grep 中的特殊表达式。- POSIX
[:alnum:]
字符类。
答案2
像这样?
egrep '(\<.+\>).+\<\1\>.+\<\1\>'
egrep
(或grep -E
)启用扩展正则表达式,这是反向引用所必需的\<.+\>
将匹配至少 1 个字符的任何单词\<
resp\>
匹配单词边界(在您的尝试中,您根本没有考虑单词边界).+
匹配一个或多个字符的序列(在您的尝试中,您使用了.*
匹配一系列零或更多字符!)
- 使用反向引用,检查匹配的序列是否出现第二次(
\1
)和第三次(\1
再次)。- 我们允许匹配之间存在一个或多个字符 ( ) 的任意序列
.+
,因此“foo bar foo dorbs foo godly”将匹配(单词“foo”出现 3 次)。 - 如果您只想匹配相邻的单词(例如“foo foo foo”),请使用类似的内容
[[:space:]]+
。
- 我们允许匹配之间存在一个或多个字符 ( ) 的任意序列
答案3
我假设你的问题意味着如果该行中的任何单词至少存在 3 次,则打印该行,否则丢弃它。我会使用awk
, 来获得更具可读性和可定制性的解决方案:
awk -F '\\W+' '{
delete c; for (i=1;i<=NF;i++) if (length($i) && ++c[$i]==3) {print; next}
}' file
这是所有字段的循环,计算它们每行出现的次数。如果任何单词达到 3 次,它将打印该行,删除数组并转到下一行。此外,还存在对字段长度的测试,以避免在计数的任何空字段上进行打印。
-F
在这里,我们可以通过添加不同和/或许多字段分隔符(支持标准 BRE 和 ERE)来轻松自定义“单词”的含义。上面的单词分隔符都是除_
和[:alnum:]
:awk -F '\\W+'
或 之外的所有字符awk -F '[^_[:alnum:]]+'
,类似于用 匹配单词边界grep
。
对于人类语言,我们可能需要不同的单词边界,就像除了字母之外的所有内容一样,例如:awk -F '[^[:alpha:]]+'
或除了字母和数字:awk -F '[^[:alnum:]]+'
或者不仅包含下划线,还包含破折号到单词中:awk -F '[^-_[:alnum:]]+'
。
如果不设置-F
,则仅使用空白字符。
答案4
GNU sed
在扩展正则表达式模式下-E
检测任意单词在一行中恰好重复 3 次的行。
$ r1='.*\<\1\>'
$ r2=$r1$r1 r3=$r2$r1
$ sed -Ee "
/\<(\w+)\>$r2/! d
/\<(\w+)\>$r3/d
" file
- Perl 使用散列将单词存储为键,并将当前行中的计数存储为值。
$ perl -lne 'my %h;
$h{$_}++ for /\w+/g;
print if grep { $_ == 3 } values %h;
' file