正規表現を使用して、grep -E
特定の順序ではなくすべての文字セットを含む単語を見つける必要があります。たとえば、すべてのコレクション(aeiou)が含まれているが、コレクションが単語内の任意の順序で表示される可能性がある単語です。
答え1
aeiou
「すべてを任意の順序で含める」という規則は、grep -E
適切なサイズのPOSIX拡張正規表現()では表現できません。
以下は、代替として使用されるaeiouの完全な120の順列のリストです。
a.*e.*i.*o.*u|a.*e.*i.*u.*o|a.*e.*o.*i.*u|a.*e.*o.*u.*i|a.*e.*u.*i.*o|a.*e.*u.*o.*i|a.*i.*e.*o.*u|a.*i.*e.*u.*o|a.*i.*o.*e.*u|a.*i.*o.*u.*e|a.*i.*u.*e.*o|a.*i.*u.*o.*e|a.*o.*e.*i.*u|a.*o.*e.*u.*i|a.*o.*i.*e.*u|a.*o.*i.*u.*e|a.*o.*u.*e.*i|a.*o.*u.*i.*e|a.*u.*e.*i.*o|a.*u.*e.*o.*i|a.*u.*i.*e.*o|a.*u.*i.*o.*e|a.*u.*o.*e.*i|a.*u.*o.*i.*e|e.*a.*i.*o.*u|e.*a.*i.*u.*o|e.*a.*o.*i.*u|e.*a.*o.*u.*i|e.*a.*u.*i.*o|e.*a.*u.*o.*i|e.*i.*a.*o.*u|e.*i.*a.*u.*o|e.*i.*o.*a.*u|e.*i.*o.*u.*a|e.*i.*u.*a.*o|e.*i.*u.*o.*a|e.*o.*a.*i.*u|e.*o.*a.*u.*i|e.*o.*i.*a.*u|e.*o.*i.*u.*a|e.*o.*u.*a.*i|e.*o.*u.*i.*a|e.*u.*a.*i.*o|e.*u.*a.*o.*i|e.*u.*i.*a.*o|e.*u.*i.*o.*a|e.*u.*o.*a.*i|e.*u.*o.*i.*a|i.*a.*e.*o.*u|i.*a.*e.*u.*o|i.*a.*o.*e.*u|i.*a.*o.*u.*e|i.*a.*u.*e.*o|i.*a.*u.*o.*e|i.*e.*a.*o.*u|i.*e.*a.*u.*o|i.*e.*o.*a.*u|i.*e.*o.*u.*a|i.*e.*u.*a.*o|i.*e.*u.*o.*a|i.*o.*a.*e.*u|i.*o.*a.*u.*e|i.*o.*e.*a.*u|i.*o.*e.*u.*a|i.*o.*u.*a.*e|i.*o.*u.*e.*a|i.*u.*a.*e.*o|i.*u.*a.*o.*e|i.*u.*e.*a.*o|i.*u.*e.*o.*a|i.*u.*o.*a.*e|i.*u.*o.*e.*a|o.*a.*e.*i.*u|o.*a.*e.*u.*i|o.*a.*i.*e.*u|o.*a.*i.*u.*e|o.*a.*u.*e.*i|o.*a.*u.*i.*e|o.*e.*a.*i.*u|o.*e.*a.*u.*i|o.*e.*i.*a.*u|o.*e.*i.*u.*a|o.*e.*u.*a.*i|o.*e.*u.*i.*a|o.*i.*a.*e.*u|o.*i.*a.*u.*e|o.*i.*e.*a.*u|o.*i.*e.*u.*a|o.*i.*u.*a.*e|o.*i.*u.*e.*a|o.*u.*a.*e.*i|o.*u.*a.*i.*e|o.*u.*e.*a.*i|o.*u.*e.*i.*a|o.*u.*i.*a.*e|o.*u.*i.*e.*a|u.*a.*e.*i.*o|u.*a.*e.*o.*i|u.*a.*i.*e.*o|u.*a.*i.*o.*e|u.*a.*o.*e.*i|u.*a.*o.*i.*e|u.*e.*a.*i.*o|u.*e.*a.*o.*i|u.*e.*i.*a.*o|u.*e.*i.*o.*a|u.*e.*o.*a.*i|u.*e.*o.*i.*a|u.*i.*a.*e.*o|u.*i.*a.*o.*e|u.*i.*e.*a.*o|u.*i.*e.*o.*a|u.*i.*o.*a.*e|u.*i.*o.*e.*a|u.*o.*a.*e.*i|u.*o.*a.*i.*e|u.*o.*e.*a.*i|u.*o.*e.*i.*a|u.*o.*i.*a.*e|u.*o.*i.*e.*a
以下は短いコードですが、入れ子のため理解するのは難しいです。
a.*(e.*(i.*[ou]|o.*[iu]|u.*[io])|i.*(e.*[ou]|o.*[eu]|u.*[eo])|o.*(e.*[iu]|i.*[eu]|u.*[ei])|u.*(e.*[io]|i.*[eo]|o.*[ei]))|e.*(a.*(i.*[ou]|o.*[iu]|u.*[io])|i.*(a.*[ou]|o.*[au]|u.*[ao])|o.*(a.*[iu]|i.*[au]|u.*[ai])|u.*(a.*[io]|i.*[ao]|o.*[ai]))|i.*(a.*(e.*[ou]|o.*[eu]|u.*[eo])|e.*(a.*[ou]|o.*[au]|u.*[ao])|o.*(a.*[eu]|e.*[au]|u.*[ae])|u.*(a.*[eo]|e.*[ao]|o.*[ae]))|o.*(a.*(e.*[iu]|i.*[eu]|u.*[ei])|e.*(a.*[iu]|i.*[au]|u.*[ai])|i.*(a.*[eu]|e.*[au]|u.*[ae])|u.*(a.*[ei]|e.*[ai]|i.*[ae]))|u.*(a.*(e.*[io]|i.*[eo]|o.*[ei])|e.*(a.*[io]|i.*[ao]|o.*[ai])|i.*(a.*[eo]|e.*[ao]|o.*[ae])|o.*(a.*[ei]|e.*[ai]|i.*[ae]))
どちらも、検索中の単語が1行に1単語ずつあるファイルにあるとします。それ以外の場合は、空白以外の文字と一致するようにすべての.
「」を変更する必要があります。[^ ]
(注:\S
from perlはおそらくgrepで使用されるエンジンを含む多くの正規表現エンジンで動作しますが、Perl準拠の正規表現は標準のgrep機能ではないためです。[^ ]
)
私はこれらの正規表現を手動で記述しようとしません。最初のコードには順列ジェネレータを使用し、2番目のコードを書くためにvimで多くのマクロ記録と再生を行いました。
しかし、問題を逆さまにひっくり返すと、何が起こるのか見てみましょう。すべてのコレクションを含む文字列を一致させようとするのではなく、反対側を一致させます。コレクションが 1 つ以上欠落しています。。
(これからは入力時に1行に1単語という仮定に固執します。)
a
一致しない単語^[^a]*$
(最初から最後までの文字以外の文字で構成a
)
e
一致しない単語一致が見つからない単語一致が見つからない単語一致が欠落 し^[^e]*$
てi
いる単語^[^i]*$
o
^[^o]*$
u
^[^u]*$
a
行方不明、行方不明、行方不明、行方e
不明、または行方不明i
のo
単語がu
一致します。
^([^a]*|[^e]*|[^i]*|[^o]*|[^u]*)$
したがって、このgrepコマンドは不要なすべての単語を提供します。
grep -E '^([^a]*|[^e]*|[^i]*|[^o]*|[^u]*)$' wordlist
便利な-v
オプションであなたの好きな言葉を得ることができますする考える:
grep -vE '^([^a]*|[^e]*|[^i]*|[^o]*|[^u]*)$' wordlist
必要に応じて追加してください-i
。
正規表現を書くときは、反転技術を念頭に置いてください。時には、非常に複雑な正規表現が単純な正規表現と反対になることもあります。
答え2
あなたは一つ grep
注文する?各コレクションを少なくとも一度(任意の順序で)含むすべての単語を見つけるには、最も簡単なコマンドは次のとおりです。
問合せ単語リスト| grep私| grepあなた|
-i
大文字と小文字の区別が必要な場合は追加してください。
答え3
grep
私の考えでは、これは実際のAND演算子がないので少しトリッキーな質問です。さまざまなトリックを使用してgrep
部分的なANDを取得できますが、場合によっては機能します。
たとえば、ワイルドカード演算子を使用して文字列をパターンと一致させることができますが、パターンとまったく同じ順序である場合にのみ一致します。
サンプルファイル
$ cat words.txt
aeiou
a1e2i3o4u5
dog
blh
spkz
uoiea
1. .* 使用例
$ grep -E ".*a.*e.*i.*o.*u.*" words.txt
aeiou
a1e2i3o4u5
aeiou
これは、同じシリーズのシーケンスを持つ文字列とのみ一致します。しかし、一致することはできませんuoiea
。
2. [aeiou] 使用例
$ grep -E [aeiou] words.txt
aeiou
a1e2i3o4u5
dog
uoiea
この方法は一致するかもしれませんが、緩すぎてパターン内の少なくとも1つの文字を含むすべての項目と一致します。
3. 複数のgrepの使用例
$ grep a words.txt | grep e | grep i | grep o | grep u
aeiou
a1e2i3o4u5
uoiea
これを強制的に使用する必要があり、grep
目的がグループ内のすべての文字を一致させることであれば、これが実際に使用できる唯一のオプションです。
4. awkの使用例
$ awk '/a/ && /e/ && /i/ && /o/ && /u/ { print }' words.txt
aeiou
a1e2i3o4u5
uoiea
Unixを扱うとき、しばしばそうです。正しいツールに切り替えたいという意志があれば、不可能に見える作業が簡単になる可能性があります。に切り替えると、awk
実際のAND演算子(&&
)を使用できるようになり、探している文字セットを指定できるようになります。
grep
5. その他スイッチ使用例(-w)
一致する文字列がすべて単一の単語で保証されている場合は、この-w
スイッチを使用できます。
-w, --word-regexp
Select only those lines containing matches that form whole words.
The test is that the matching substring must either be at the
beginning of the line, or preceded by a non-word constituent
character. Similarly, it must be either at the end of the line or
followed by a non-word constituent character. Word-constituent
characters are letters, digits, and the underscore.
したがって、セットの一連の文字が連続[aeiou]
している限り、次のようにこのスイッチを利用できます。
$ grep -Ew "*[aeiou]*" words.txt
aeiou
uoiea
ただし、マルチケース構文を処理する必要がある場合でも失敗します。
$ echo "I love Fort Lauderdale" | grep -Ew "*[aeiou]*"
$
-i
ただし、大文字と小文字を区別しないスイッチを使用するとgrep
再び機能します。
$ echo "I love Fort Lauderdale" | grep -Ewi "*[aeiou]*"
I love Fort Lauderdale