次のコマンドを変更して、正規表現が少なくとも 3 aではなく正確に 3 aを含む/ usr/share/dict/words内の単語と一致するようにします。
cat /usr/share/dict/words | grep "a.*a.*a" | grep -v "'s$" | wc -l
どうすればよいですか?
_[^a]
_(任意の文字に一致)の代わりに_.
_(a
以外の任意の文字に一致)を使用する方法の1つを次に示します。
_$ 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]*$
_と同等です。パフォーマンスははるかに優れていますが、ギガバイト単位のデータを調べている場合を除き、重要ではありません。
_^
_および_$
_正規表現アンカー演算子を明示的に使用する代わりに、暗黙的にそれを行う_-x
_オプションを使用することもできます。大文字小文字を区別せずに照合する_-i
_オプションも参照してください(ロケールに応じて):
_grep -xiE '([^a]*a){3}[^a]*'
_
同じ種類のパターンを使用して「少なくとも4つのa
s」を検出し、一致の意味を反転させます。
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}'
または、フィールド区切り文字としてawk
とa
を使用して、フィールドをカウントします。
awk -F a 'NF == 4' /usr/share/dict/words
(a
sが3つある行には、4つのフィールドがあります)
または、Perlのtr
演算子を使用して、各行のa
sの数をカウントします。
Perl -ne 'print if (tr/a/a/ == 3)' /usr/share/dict/words
演算子は文字変換の数を返し、各a
を別のa
に置き換えるため、実際の出力は変更されません。