Obtenez toutes les combinaisons possibles d'un mot en lettres minuscules / majuscules

14

Je veux écrire un script bash pour imprimer toutes les permutations minuscules et majuscules possibles d'un certain mot, par exemple harley:

harley
harleY
harlEy
harLey
...
HARLey
HARLEy
HARLEY

Ma solution naïve consiste à écrire un n-ème (n est len ​​(mot)) imbriqué for-loop pour ce mot spécifique:

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

Cependant, je devrais à nouveau coder le script pour un mot différent.

Existe-t-il une meilleure façon d'accomplir cela?

polym
la source

Réponses:

18

Une solution légèrement meilleure:

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

Pour une évolutivité totale:

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

Si vous devez absolument avoir un mot par ligne, choisissez

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

grâce au commentaire de mattdm

La version évolutive correspondante serait:

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

Pour le plaisir, essayez de remplacer "harley" par "supercalifragilisticexpialidocious" Cela fait 5 minutes et mon ordinateur continue de croquer sur celui-ci et ne finira probablement jamais :)

Joseph R.
la source
1
pour w dans {h, H} {a, A} {r, R} {l, L} {e, E} {y, Y}; do echo $ w; done
mattdm
4
Une solution un par ligne encore plus simple:printf '%s\n' {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y}
John1024
2
@ John1024 Je vous encourage à poster cela comme réponse, c'est une fonctionnalité sous-estimée de bash'sprintf
steeldriver
10
eval echo $ (echo " word " | sed 's /./ {\ U &, \ L &} / g')
  • sed 's/./{&,&}/g'transformerait Fooen {F,F}{o,o}{o,o}, ce qui serait assez inutile. Mais ajoutez \Uet \Let vous obtenez les majuscules et les minuscules de chaque lettre; à savoir {F,f}{O,o}{O,o}.
  • Il suffit ensuite de evaldire au shell de développer le { X , x séquences d'accolades }.
Scott
la source
1
Joli tour :). Si je pouvais accepter deux réponses, la vôtre serait également acceptée! Upvote quand même
polym
5

EDIT 2: Cette réponse est fausse. Il ne produit pas 2 ^ n combinaisons comme il se doit.

ÉDITER: Je ne sais pas pourquoi, mais cette solution est vraiment rapide par rapport à la solution perl de @Joeseph R. Elle exécute "Supercalifragilisticexpialidocious" en moins de 0,3 seconde!

Voici ma fissure:

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

L'exécuter:

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

N'hésitez pas à le fork et à le modifier, je suis sûr qu'il peut être optimisé. https://gist.github.com/ryanmjacobs/4c02ad80f833dee0c307

ryanmjacobs
la source
1
Le code n'imprime clairement pas tous les résultats. Avec harleyvous devriez avoir 64 résultats, où est harLEY, par exemple?
Denis
1
@Denis Yup, vous avez raison. Chaque fois, il devrait y avoir 2 ^ n résultats, où n est le nombre de caractères de la chaîne d'origine. Cette réponse est fausse.
ryanmjacobs
0

Si vous préférez utiliser des outils prêts à l'emploi au lieu de coder, vous pouvez utiliser TextMechanic (outil générateur de permutation / combinaison) et Unit-Conversion.info

Mélangé
la source
Comment obtiendraient-ils et utiliseraient-ils ces outils exactement?
Jeff Schaller
Cette réponse pourrait être grandement améliorée en ajoutant quelques détails tels que les pages d'accueil ou les référentiels GitHub pour ces projets et / ou s'ils peuvent être installés à partir d'un package.
Anthony Geoghegan