3

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.

3
  • 1
    You are trying to use extended regex. You need the -E flag for grep.
    – jordanm
    May 2, 2016 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, 2016 at 21:41
  • The digit-length distribution is far from random, see 'Note:' in my answer below.
    – agc
    May 2, 2016 at 21:55

2 Answers 2

3

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.

0
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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .