2

Here I have a bash "one-liner": cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 16 | grep '[0-9]', which generate 16 lines of 16 character alphanumeric strings.

Example of output:

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

I need to get from these strings numbers of specified (range of) length, e. g. I'd like to get numbers from E4wla28wqm3681rX, which range of length is 4 to 16. The result supposed to be 3681.

I tried to modify last grep to a form like this: grep -o '[0-9]{4,16}', but it gives nothing at all, even without head -n 16 part. With grep '[0-9]*' I'm getting every number (not digit!) of given string in separate lines, e. g. from E4wla28wqm3681rX I get:

4
28
3681

Things like grep -o '[0-9]+', grep -o '[0-9]{1}' or grep -o '[0-9]{1, }' give nothing as well.

Please, could someone help me with this problem? Or at least could You tell me what's wrong with "greps" mentioned above?

Sorry for any grammatical errors.

  • 1
    You are trying to use extended regex. You need the -E flag for grep. – jordanm May 2 '16 at 20:53
  • Is the goal to have a random distribution of 4-16 digit numbers? If so, the numbers of a given length are probably random, but using that method I'm not sure the length distribution is. – agc May 2 '16 at 21:41
  • The digit-length distribution is far from random, see 'Note:' in my answer below. – agc May 2 '16 at 21:55
0

To get the familiar regexps working you need to enable "extended regular expressions" with the flag '-E'. With that, your regexp should work:

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

The -P flag (Perl-compatible regular expressions), which some distributions support, is not necessary in this case.

1

Unfolding that one-liner and rearranging a bit, plus a few tweaks, gets:

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

Outputs:

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

Note: the n-digit numbers are probably random if taken alone, but the digit-length distribution is not. Here's a run of 1000000, all digits changed to 'x', sorted, then counted:

 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

Outputs:

 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

We can see that the more digits, the more unlikely a number is. In a million numbers only two are 12 digits, and none are 13-16 digits.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.