这里我有一个 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
。
我尝试将 last 修改grep
为这样的形式:grep -o '[0-9]{4,16}'
,但它根本没有给出任何内容,即使没有head -n 16
部分。grep '[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 位数字可能是随机的,但数字长度分布是不是。这是 1000000 的运行,所有数字都更改为“x”,排序,然后计数:
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
我们可以看到,数字越多,数字就越不可能。一百万个数字中只有两个是 12 位数字,没有一个是 13-16 位数字。