以小写/大写字母获取单词的所有可能组合

pol*_*lym 14 bash string

我想编写一个 bash 脚本来打印某个单词的所有可能的大小写排列,例如 harley:

harley
harleY
harlEy
harLey
...
HARLey
HARLEy
HARLEY
Run Code Online (Sandbox Code Playgroud)

我天真的解决方案是为此特定单词编写第 n 个(n 是 len(word))嵌套 for 循环:

#!/bin/bash
for a in {h,H}; do
    for b in {a,A}; do
    ...
    done
done
Run Code Online (Sandbox Code Playgroud)

但是,我将不得不再次为不同的单词编写脚本。

有没有更好的方法来实现这一点?

Jos*_* R. 20

一个稍微好一点的解决方案:

echo {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y}
Run Code Online (Sandbox Code Playgroud)

对于完全可扩展性:

echo harley \
| perl -nle 'print "echo ",
                    join "",map { "{" . lc . "," .uc ."}" } split //' \
| xargs -I {} bash -c "{}"
Run Code Online (Sandbox Code Playgroud)

如果您绝对必须每行一个单词,请使用

for w in {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y};do echo $w;done
Run Code Online (Sandbox Code Playgroud)

感谢mattdm 的评论

相应的可扩展版本将是:

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

为了好玩,尝试用“ supercalifragilisticexpialidocious”替换“harley”。已经过了 5 分钟了,我的电脑仍在处理这个问题,可能永远不会完成:)

  • 一个更简单的一行一行的解决方案:`printf '%s\n' {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y}` (4认同)
  • @John1024 我鼓励您将其作为答案发布,这是 bash 的“printf”的一个被低估的功能 (2认同)

Sco*_*ott 10

eval echo $(echo " word " | sed 's/./{\U&,\L&}/g')
  • sed 's/./{&,&}/g'Foo变成{F,F}{o,o}{o,o},这将是非常无用的。但是加上\Uand\L你就得到了每个字母的大小写;即,{F,f}{O,o}{O,o}
  • 然后使用eval告诉 shell 扩展 { X , x } 大括号序列是一个简单的问题。


rya*_*obs 5

编辑 2:这个答案是错误的。它不会产生 2^n 组合,因为它应该。

编辑:我不知道为什么,但这个解决方案真的快相比,@Joeseph R. perl的解决方案。它运行“Supercalifragilisticexpialidocious”在小于0.3秒!

这是我的破解:

#!/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
Run Code Online (Sandbox Code Playgroud)

运行它:

$ ./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
Run Code Online (Sandbox Code Playgroud)

随意 fork 和修改它,我相信它可以优化。https://gist.github.com/ryanmjacobs/4c02ad80f833dee0c307