Como obter números de comprimento especificado (intervalo de) da string com grep?

2

Aqui eu tenho um bash "one-liner": cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 16 | grep '[0-9]' , que gera 16 linhas de 16 caracteres alfanuméricos.

Exemplo de saída:

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

Eu preciso obter esses números de strings de comprimento especificado (intervalo de), e. g. Eu gostaria de obter números de E4wla28wqm3681rX , cujo intervalo de comprimento é de 4 a 16. O resultado deveria ser 3681 .

Eu tentei modificar o último grep para um formulário como este: grep -o '[0-9]{4,16}' , mas não fornece nada, mesmo sem head -n 16 part. Com grep '[0-9]*' , estou obtendo cada número (não dígito!) Da string dada em linhas separadas, e. g. de E4wla28wqm3681rX eu recebo:

4
28
3681

Coisas como grep -o '[0-9]+' , grep -o '[0-9]{1}' ou grep -o '[0-9]{1, }' também não oferecem nada.

Por favor, alguém poderia me ajudar com esse problema? Ou pelo menos você poderia me dizer o que há de errado com "greps" mencionados acima?

Desculpe por quaisquer erros gramaticais.

    
por Coro 02.05.2016 / 22:39

2 respostas

0

Para obter o regexps familiar, é necessário ativar "expressões regulares estendidas" com o sinalizador '-E'. Com isso, seu regexp deve funcionar:

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

O -P flag (expressões regulares compatíveis com Perl), que algumas distribuições suportam, não é necessário neste caso.

    
por 02.05.2016 / 23:39
1

Desdobrar esse one-liner e reorganizar um pouco, além de alguns ajustes, fica:

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

Saídas:

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

Nota: os números de n dígitos são provavelmente aleatórios se considerados isoladamente, mas a distribuição de comprimento de dígitos não é . Aqui está uma corrida de 1000000, todos os dígitos mudaram para 'x', classificados e contados:

 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

Saídas:

 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

Podemos ver que quanto mais dígitos, mais improvável é um número. Em um milhão de números, apenas dois são 12 dígitos e nenhum tem 13-16 dígitos.

    
por 02.05.2016 / 23:39