grepを使用して文字列から指定された(範囲)長さを取得するには?

grepを使用して文字列から指定された(範囲)長さを取得するには?

ここにbash "one-liner"があります。cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 16 | grep '[0-9]'これにより、16文字の英数字文字列で構成される16行が生成されます。

出力例:

nZ3BED8FYGNkYMGc
zu83X7pgqLX36q2B
mocN9MhYoXzOwKkO
Ly2lfakdJXcX3J1s
I3Zezk8wkwkX7wKg
UZh36waccItxARGN
7qxJSnpKRcPR6Vki
fhTW3wd0ftygKxET
YQzKUxhBdEQ3O2rY
fy2tcApkl5KYOjYe
F05WqnwMRGIevzh9
q2c86PsKGlJkjijp
h6ig7eXzPhjY75h7
PX0ikEW2z8ptQsAI
M5mdMSvQmvmWF5yS
GCPqQklXHc8H2Kmv

この文字列から指定された長さ(範囲)の数を取得する必要があります。たとえば、から数字を取得するには、長さのE4wla28wqm3681rX範囲は4〜16です。結果は次のとおりです3681

grep最後を次のように修正しようとしましたが、セクションがgrep -o '[0-9]{4,16}'なくてもまったく何も提供しません。与えられた文字列の各数字(数字ではない!)を別々の行に表示します。たとえば、次のようになります。head -n 16grep '[0-9]*'E4wla28wqm3681rX

4
28
3681

grep -o '[0-9]+'のようなものgrep -o '[0-9]{1}'や何も提供されていませんgrep -o '[0-9]{1, }'

誰でもこの問題を解決するのに役立ちますか?それとも、少なくとも上記の「greps」にどのような問題があるのか​​教えてください。

文法エラーについてお詫び申し上げます。

答え1

使い慣れた正規表現が正しく機能するには、「-E」フラグを使用して「拡張正規表現」を有効にする必要があります。これにより正規表現が機能します。

... | grep -E -o '[0-9]{4,16}' 

この場合、一部のディストリビューションでサポートされているフラグ-P(Perl互換正規表現)は必要ありません。

答え2

その単一行を展開し、少し並べ替えていくつかの調整を行うと、次のような結果が得られます。

cat /dev/urandom | \
    tr -dc 'a-zA-Z0-9' | \
    fold -w 16 | \
    tr -d '[A-z]' | \
    grep '....' | \
    head -n 16

出力:

7405935
60722
11225
96954
3966
8774
539418
1964
59150
5994
1086
7470
2751
8534
21501
14927

注:個別に見ると、n桁の数字はランダムである可能性がありますが、数字の長さの分布は次のとおりです。いいえ。以下は、すべての数字が「x」に変更されソートされた後に計算された1,000,000の実行です。

 cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | \
    tr -d '[A-z]' | grep '....' | head -n 1000000 | \
    tr '[0-9]' x | sort | uniq -c | nl -v 4

出力:

 4   594210 xxxx
 5   275196 xxxxx
 6    96871 xxxxxx
 7    26838 xxxxxxx
 8     5738 xxxxxxxx
 9      997 xxxxxxxxx
10      134 xxxxxxxxxx
11       14 xxxxxxxxxxx
12        2 xxxxxxxxxxxx

数字が高いほど、数字が出る可能性が低くなることがわかります。百万の数字のうち、2つだけが12桁で、13〜16桁は1つもありません。

関連情報