Obtenga todas las combinaciones posibles de una palabra en letras minúsculas / mayúsculas

14

Quiero escribir un script bash para imprimir todas las posibles permutaciones en mayúsculas y minúsculas de una palabra determinada, por ejemplo, harley:

harley
harleY
harlEy
harLey
...
HARLey
HARLEy
HARLEY

Mi solución ingenua es escribir un n-ésimo (n es len (palabra)) anidado for-loop para esta palabra específica:

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

Sin embargo, tendría que codificar el script para una palabra diferente nuevamente.

¿Hay una mejor manera de lograr esto?

polimero
fuente

Respuestas:

18

Una solución un poco mejor:

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

Para una escalabilidad completa:

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

Si absolutamente debe tener una palabra por línea, vaya con

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

gracias al comentario de mattdm

La versión escalable correspondiente sería:

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

Por diversión, intente reemplazar "harley" por "supercalifragilisticexpialidocious" Han pasado 5 minutos y mi computadora aún no funciona y probablemente nunca terminará :)

Joseph R.
fuente
1
para w en {h, H} {a, A} {r, R} {l, L} {e, E} {y, Y}; do echo $ w; hecho
mattdm
44
Una solución aún más simple de una por línea:printf '%s\n' {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y}
John1024
2
@ John1024 Te animo a publicar eso como respuesta, es una característica poco apreciada de bashprintf
steeldriver
10
eval echo $ (echo " palabra " | sed 's /./ {\ U &, \ L &} / g')
  • sed 's/./{&,&}/g'se convertiría Fooen {F,F}{o,o}{o,o}, lo que sería bastante inútil. Pero agregue \Uy \Lobtendrá la mayúscula y minúscula de cada letra; es decir, {F,f}{O,o}{O,o}.
  • Entonces es una simple cuestión de usar evalpara decirle al shell que expanda las secuencias de llaves { X , x }.
Scott
fuente
1
Buen truco :). Si pudiera aceptar dos respuestas, ¡la suya también sería aceptada! Voto de todos modos
2014
5

EDITAR 2: Esta respuesta es incorrecta. No produce 2 ^ n combinaciones como debería.

EDITAR: No sé por qué, pero esta solución es realmente rápida en comparación con la solución perl de @Joeseph R. ¡Ejecuta "Supercalifragilisticexpialidocious" en menos de 0.3 segundos!

Aquí está mi crack:

#!/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

Ejecutándolo:

$ ./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

Siéntase libre de bifurcarlo y modificarlo, estoy seguro de que puede optimizarse. https://gist.github.com/ryanmjacobs/4c02ad80f833dee0c307

ryanmjacobs
fuente
1
El código claramente no imprime todos los resultados. Con harleyusted debería tener 64 resultados, ¿dónde está harLEY, por ejemplo?
Denis
1
@ Denis Sí, tienes razón. Cada vez debe haber 2 ^ n resultados, donde n es el número de caracteres de la cadena original. Esta respuesta es incorrecta.
ryanmjacobs
0

Si prefiere usar herramientas listas en lugar de codificación, puede usar TextMechanic (herramienta de generación de permutación / combinación) y Unit-Conversion.info

Mezclado
fuente
¿Cómo obtendrían y usarían esas herramientas exactamente?
Jeff Schaller
Esta respuesta podría mejorarse enormemente agregando algunos detalles, como las páginas de inicio o los repositorios de GitHub para estos proyectos y / o si se pueden instalar desde un paquete.
Anthony G - justicia para Monica