grepで単純な正規数量子式を使用する

grepで単純な正規数量子式を使用する

ls | xargs -n 1 basename | grep -E '[0-9]{1}'なぜ0〜9の間の単一の数字しか表示されないのを知っている人はいますか?

たとえば、次のような場合があります。

touch 1
touch 22
touch 333
touch test_file

私が実行した場合ls | xargs -n 1 basename | grep -P '[0-9]{1}'

1、22、333個のファイルがリストされています。

私が実行した場合ls | xargs -n 1 basename | grep -P '[0-9]{2}'

22個と333個のファイルがリストされています。

私は{2}が22個のファイルのみを表示したいと思います。

答え1

私の考えでは、あなたが現在起こっているものとは異なることを期待する理由は、あなたが受け入れているからだと思います。

[0-9]{n}

これは[0-9]のn個の文字だけを一致させ、残りは捨てることを意味しますが、実行する操作は[0-9]のn個の文字を見つけて一致と呼ぶことです。だから

[0-9]{1}

いつでも[0-9]と一致する項目を正確に探すので、1つは一致し、22個を確認すると最初の2つで止まり、残りは見ずに一致すると思います。 333も同じだ。指定した場合

[0-9]{2}

1つに一致せず、22のゲームと一致し、次に333のゲームのうち33のゲームと一致するのでインポートします。

slmが言ったように、ここでは単語の境界が重要です。あなたの質問に一致するgrep正規表現には、-Pスタイルと-Eスタイルの両方があります。次のように、-EでGNU \ <と\>を使用できます。

ls | xargs -n 1 basename | grep -E '\<[0-9]{1}\>'

または \b は、次のように -E または pcre -P と一致します。

ls | xargs -n 1 basename | grep -P '\b[0-9]{1}\b'

答え2

grep -x行内で一致するものではなく、正確な一致を見つけるために使用されます。

grep fooを含む行を検索foo、また、grep -x foo次を含む行を検索はい foo

同様にgrep -E '[0-9]{1}'(と同じgrep '[0-9]')は、1桁の数字を含む行を探します。grep -xE '[0-9]{1}'1桁の数字で構成される行を探します。

GNUでは、またはオプションを使用して一致するものを確認grepできます。もちろん、すべての一致が表示されます。--color-o

答え3

これは、最初の2文字が333正規表現と一致するため、行全体が一致するためです。

これを回避するには、次のものを使用できます。

(^|[^0-9])[0-9]{2}([^0-9]|$)

答え4

例の内容をテキストファイルに入れると、grep一致する理由を確認できます。

$ grep -E '[0-9]{1}' file.txt
touch 1
touch 22
touch 333

単語境界()を使用すると、一致する文字列ではなく、正規表現()の単一の単語のみを一致させる-wことを示します。grep\<REGEX\>

$ grep -Ew '\<[0-9]{1}\>' file.txt
touch 1

$ grep -Ew '\<[0-9]{2}\>' file.txt
touch 22

$ grep -Ew '\<[0-9]{3}\>' file.txt
touch 333

\<境界がどこにあるのか教えてください\>grepこれにより、grep明示的な単語(例:1)は一致しますが、文字列(例:11、111、またはaa11aa)は一致しません。なぜなら、これらの文字列の正規表現が単語の境界内に含まれていないからです。

関連情報