Se nada mais, você precisa de uma declaração case
.
random(){
printf "%d^${2##*[!0-9]*}\n" "$(($(
export LC_ALL=C; a=$1
while x=${a%"${a#?}"} s=
case $a in
([a-z]-["$x"-z]*|[A-Z]-["$x"-Z]*)
a=${a#??} s=?
printf '(%d-%d+1)+' "'$a" "'$x";;
([0-9]-["$x"-9]*)
x=${a%"${a#???}"} a=${a#"$x"}
printf "$((-($x)+1))+";;
(?-*) a=${a#??}
echo 2+;;
(?*) x=${a%%[A-Za-z0-9]-*}
a=${a#"$x"}
echo "${#x}+";;
(*) ! echo 0 ;;esac
do a=${a#$s} ; done
)))" | bc| sed 's/$/ possibilities./
/^1 /s/....$/y./'
}
Ok, eu tenho que me desculpar - eu só agora percebi que o que eu achava que eram classes de caracteres eram sequências de caracteres literais - e que você estava analisando-as. Agora eu entendo o que você é. Eu fiz isso funcionar agora - ele realmente faz os intervalos, e você pode lidar com qualquer tipo de personagem - porque isso conta a diferença.
{ random A 1 #1 char and 1
random AB 1 #2 chars and 1
random a-Z 1 #3 chars because the range is invalid and 1
random aa-c 1 #4 chars: aabc and 1
random a-c 2 #3 chars: abc and 2
random aa-z 3) #27 chars:aa-z and 3
}
OUTPUT
1 possibility.
2 possibilities.
3 possibilities.
4 possibilities.
9 possibilities.
19683 possibilities.
A primeira coisa que é feita é tentar printf
nosso segundo argumento - que sofre% de expansão do parâmetro${2##*[!0-9]*}
para torná-lo nulo se contiver qualquer caractere não numérico - precedido pelo valor %d
igit de um expansão aritmética em que todo o nosso ciclo de execução ocorre. De fato, a função inteira é uma instrução printf
da perspectiva do shell atual.
Mas na expansão $((
math ))
é uma substituição do comando $(
)
- e isso é tudo. Nós fornecemos sem números - é apenas $(($()))
.
Exceto que a subshell dentro da substituição de comando executa nosso loop e coleta nossa saída. Nossa saída eventualmente resulta em uma expressão aritmética viável.
Dentro do loop sempre colocamos o primeiro caractere de $a
em $x
no topo de cada um. Em seguida, verificamos a cabeça do nosso valor atual para $a
em relação a alguns padrões case
. A primeira delas é assim:
([a-z]-["$x"-z]*|[A-Z]-["$x"-Z]*)
Aqui, usamos o primeiro caractere de $a
- que salvamos em $x
- duas vezes. Em primeiro lugar, é o argumento contra o qual comparamos nosso padrão. Mas, em segundo lugar, é um limitador para o terceiro caractere de $a
- garante que o terceiro caractere não apenas se encaixe em uma faixa alfabética, mas também que seja maior ou igual a primeiro caractere de $a
personagem. Porque z-a
é um intervalo inválido e não corresponde quando usamos $x
para testar.
Se correspondermos a esse padrão, imprimiremos o valor do dígito ascii de cada $x
e $a
depois de removermos da cabeça $a
dois caracteres.
Assim:
printf '(%d-%d+1)+' "'$x" "'$a"
... que se torna uma subexpressão parantética na nossa aritmética final e avalia a distância entre o nosso alcance.
Fazemos o mesmo para os dígitos:
([0-9]-["$x"-9]*)
E também tiramos a cabeça de $a
nesse caso. A matemática para os dígitos é um pouco diferente - temos o negativo. Os primeiros três caracteres de $a
são salvos em $x
, como x=4-9
.
E assim imprimimos:
printf "$((-($x)+1))+"
No caso de o cabeçalho de $a
parecer como um intervalo, mas ainda assim falhar nos dois testes anteriores e corresponder ao nosso padrão (?-*)
, então removeremos o topo dois caracteres, echo 2+
e ciclo novamente.
Se chegarmos ao ponto tão baixo quanto o padrão (?*)
, então removeremos a faixa de $a
de tudo até a primeira correspondência de intervalo possível em $a
. Se tivermos sucesso, continuaremos a fazer o loop e apenas dividiremos a diferença, mas se não houver correspondência possível no intervalo no restante de $a
, sairemos do loop porque consumiremos todo o $a
right aqui e echo ${#a}+
, basicamente.
Bem, não vamos sair ainda - o loop nunca sai até que $a
seja enviado de volta ao topo do loop vazio. Quando isso acontece, fazemos ! echo 0
, que é a última string que escrevemos para a saída.
Então, volte ao shell atual e avalie tudo na expansão matemática para imprimir "$((subshell_math))^$2"
at bc
cuja saída é canalizada para sed
, que acrescenta a string possibles.
à sua saída.
E é assim que funciona.