grep - 正则表达式将在字符串中精确找到 3 个 a

grep - 正则表达式将在字符串中精确找到 3 个 a

我想更改以下命令,以便正则表达式匹配 /usr/share/dict/words 中包含的单词确切地3 a 代替至少3个a。

cat /usr/share/dict/words | grep "a.*a.*a" | grep -v "'s$" | wc -l

我该怎么做呢?

答案1

这是使用[^a](匹配除 之外的任何字符a) 而不是.(匹配任何字符) 的一种方法:

$ grep -E '^([^a]*a){3}[^a]*$' /usr/share/dict/cracklib-small | shuf -n 4
areaway
humanitarian
capitalizations
autonavigator

您也可以像这样编写正则表达式,^[^a]*(a[^a]*){3}$得到相同的结果。

当您需要不同数量的 a 时,它也相当于^[^a]*a[^a]*a[^a]*a[^a]*$无法缩放。虽然性能要好得多,但这并不重要,除非您正在处理千兆字节的数据。

您还可以使用隐式执行此操作的选项,而不是显式使用^和regexp 锚运算符。另请参阅不区分大小写匹配的选项(根据区域设置):$-x-i

grep -xiE '([^a]*a){3}[^a]*'

答案2

使用相同类型的模式来检测“至少 4 as”,并反转匹配的含义:

grep 'a.*a.*a' /usr/share/dict/words | grep -v 'a.*a.*a.*a'

或者,

grep '\(a.*\)\{3\}' /usr/share/dict/words | grep -v '\(a.*\)\{4\}'

或者,

grep -E '(a.*){3}' /usr/share/dict/words | grep -v -E '(a.*){4}'

或者,使用awkwitha作为字段分隔符并对字段进行计数:

awk -F a 'NF == 4' /usr/share/dict/words

(在具有三个 s 的行上a,将有四个字段)


或者,使用 Perl 的运算符来计算每行上 str的数量:a

perl -ne 'print if (tr/a/a/ == 3)' /usr/share/dict/words

该运算符返回进行的音译次数,我们将每个音译替换a为另一个a,因此实际输出不会被修改。

相关内容