如何使用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

我尝试将 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 位数字。

相关内容