web-dev-qa-db-ja.com

grep-文字列で正確に3つのaを見つける正規表現

次のコマンドを変更して、正規表現が少なくとも 3 aではなく正確に 3 aを含む/ usr/share/dict/words内の単語と一致するようにします。

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

どうすればよいですか?

9
rplee

_[^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]*'
_
17
frostschutz

同じ種類のパターンを使用して「少なくとも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}'

または、フィールド区切り文字としてawkaを使用して、フィールドをカウントします。

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

asが3つある行には、4つのフィールドがあります)


または、Perlのtr演算子を使用して、各行のasの数をカウントします。

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

演算子は文字変換の数を返し、各aを別のaに置き換えるため、実際の出力は変更されません。

13
Kusalananda