Obter todas as combinações possíveis de uma palavra em letras maiúsculas / minúsculas

14

Eu quero escrever um script bash para imprimir todas as permutações possíveis de maiúsculas e minúsculas de uma determinada palavra, por exemplo, harley:

harley
harleY
harlEy
harLey
...
HARLey
HARLEy
HARLEY

Minha solução ingênua é escrever um n-ésimo (n é len (word)) aninhado for-loop para esta palavra específica:

#!/bin/bash
for a in {h,H}; do
    for b in {a,A}; do
    ...
    done
done

No entanto, eu teria que codificar o script para uma palavra diferente novamente.

Existe uma maneira melhor de conseguir isso?

polym
fonte

Respostas:

18

Uma solução um pouco melhor:

echo {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y}

Para escalabilidade total:

echo harley \
| perl -nle 'print "echo ",
                    join "",map { "{" . lc . "," .uc ."}" } split //' \
| xargs -I {} bash -c "{}"

Se você precisar absolutamente de uma palavra por linha, vá com

for w in {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y};do echo $w;done

graças ao comentário de mattdm

A versão escalável correspondente seria:

echo harley \
| perl -nle 'print join "",map { "{" . lc . "," .uc ."}" } split //' \
| xargs -I {} bash -c 'for w in {};do echo $w;done'

Por diversão, tente substituir "harley" por "supercalifragilisticexpialidocious" Já faz 5 minutos e meu computador ainda está analisando este e provavelmente nunca terminará :)

Joseph R.
fonte
1
para w em {h, H} {a, A} {r, R} {l, L} {e, E} {y, Y}; do echo $ w; done
mattdm
4
Uma solução uma por linha ainda mais simples:printf '%s\n' {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y}
John1024
2
@ John1024 Encorajo-vos a postar isso como uma resposta, é um recurso subestimado do bash deprintf
steeldriver
10
eval echo $ (eco " palavra " | sed 's /./ {\ U &, \ L &} / g')
  • sed 's/./{&,&}/g'giraria Fooem {F,F}{o,o}{o,o}, o que seria bastante inútil. Mas adicione\U e \Le você começa a maiúsculas e minúsculas de cada letra; ou seja, {F,f}{O,o}{O,o}.
  • Então é simples usar evalo comando para dizer ao shell para expandir as seqüências de chaves { X , x }.
Scott
fonte
1
Bom truque :). Se eu pudesse aceitar duas respostas, as suas também seriam aceitas! Voto positivo de qualquer maneira
polym
5

EDIT 2: Esta resposta está errada. Não produz 2 ^ n combinações como deveria.

EDIT: Eu não sei por que, mas esta solução é realmente rápida em comparação com a solução perl de @Joeseph R. Ele roda "Supercalifragilisticexpialidocious" em menos de 0,3 segundos!

Aqui está a minha rachadura:

#!/bin/bash

str=${1^^}  # convert to uppercase
len=${#str} # get length of string

for ((perm=0; perm <= len; perm++)); do
    for ((i=0; i <= len; i++)); do
        lower=${str,,}   # convert to lowercase

        # Uppercase n-th letter for permutation
        if [ $perm -gt 0 ]; then
            nth=${lower:perm-1}
            lower=$(echo ${lower:0:perm-1}${nth^})
        fi

        echo -n ${str:0:i} # print orig string from 0 to $i
        echo ${lower:i}    # print new string from $i to end
    done
done | sort -u

Executando:

$ ./permutations.sh hi
hi
hI
Hi
HI

$ ./permutations.sh harley
harley
harleY
harlEy
harLey
haRley
hArley
Harley
HarleY
HarlEy
HarLey
HaRley
HArley
HArleY
HArlEy
HArLey
HARley
HARleY
HARlEy
HARLey
HARLeY
HARLEy
HARLEY

Sinta-se livre para bifurcar e modificá-lo, tenho certeza de que pode ser otimizado. https://gist.github.com/ryanmjacobs/4c02ad80f833dee0c307

ryanmjacobs
fonte
1
O código claramente não imprime todos os resultados. Com harleyvocê deve ter 64 resultados, onde está harLEY, por exemplo?
Denis
1
@ Denis Yup, você está certo. Sempre que deve haver 2 ^ n resultados, em que n é o número de caracteres da string original. Esta resposta está errada.
Ryanmjacobs
0

Se você preferir usar ferramentas prontas em vez de codificar, poderá usar o TextMechanic (ferramenta de gerador de permutação / combinação) e o Unit-Conversion.info

Misturado
fonte
Como eles poderiam obter e usar essas ferramentas exatamente?
Jeff Schaller
Esta resposta pode ser bastante aprimorada adicionando alguns detalhes, como as páginas iniciais ou os repositórios do GitHub para esses projetos e / ou se eles podem ser instalados a partir de um pacote.
Anthony G - Justice para Monica