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.