$ printf 'asf .test. afd\nasaf foo-test asfdads\n'
asf .test. afd
asaf foo-test asfdads
$ printf 'asf .test. afd\nasaf foo-test asfdads\n' | grep -w test
asf .test. afd
asaf foo-test asfdads
質問:「foo-test」と一致させるにはどうすればよいですか?より正確に言うと、「-w」は「-」を区切り文字として使用しますが、「。」は使用しないでください?
つまり、grep
に、.
がwordsを構成する文字の中にあり、Word borderがないことを伝えることができますか。 .
とtest
の間に?
または、grep以外のソリューションはありますか?
2.19より前のバージョンでは、GNU grep
's -w
は1バイト文字の英数字とアンダースコアのみを考慮します(したがって、UTF-8ロケールでは、26 + 26のみ) + 10 + 1(ASCII文字、数字、アンダースコア))を単語の構成要素として使用します。たとえば、echo Stéphane | grep -w St
は一致します。これは2.19で修正されました。
ただし、ロジックは手動で実装できます。
grep -E '([^[:alnum:]_.]|^)test([^[:alnum:]_.]|$)'
つまり、test
の前に、単語以外の構成要素または行の先頭があり、その後に単語以外の構成要素または行の終わりが続きます。
(上記の[:alnum:]
は、ロケール内の数字と文字に一致します。ASCIIのものだけでなく、ASCIIのもののみ)が必要な場合は、ロケールをCに修正してください) 。
Word以外の構成要素を取り巻くものを一致に含めたくない場合(たとえば、GNUの-o
を使用しているため)、今回はPCRE正規表現とルックアラウンド演算子を使用できます。
grep -Po '(*UCP)(?<![\w.])test(?![\w.])'
(*UCP)
を削除し、LC_ALL=C
を追加して、ASCII文字と数字のみに一致するようにします。
正規表現の先頭で(*UCP)
を使用すると、PCREライブラリに̲niC̲odeP̲ropertiesを\w
に使用する必要があることが通知されます。
これがないと、\w
はロケールの英数字とアンダースコアに一致しますが、シングルバイト文字の場合のみです。これは、ASCIIのものだけが一致するUTF-8ロケール(現在の標準)では機能しません。(*UCP)
はUTF-8でも機能します。一致します。ロケールとは異なる可能性のあるPCRE独自の文字プロパティの概念に基づいていますが、GNUシステムでは、UTF-8ロケール定義と同様に、不完全で古くなっています(少なくとも2015-04の)。