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

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

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

harley
harleY
harlEy
harLey
...
HARLey
HARLEy
HARLEY

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

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

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

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

答案1

稍微好一点的解决方案:

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

为了实现完全的可扩展性:

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

如果你必须每行一个单词,那么就使用

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

谢谢mattdm 的评论

相应的可扩展版本是:

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

为了好玩,尝试将“harley”替换为“超级加州脆弱性Expialidocious”已经 5 分钟了,我的电脑仍在处理这个问题,可能永远无法完成:)

答案2

评估回声$(回声“单词" | sed 's/./{\U&,\L&}/g')
  • sed 's/./{&,&}/g'Foo变成{F,F}{o,o}{o,o},这将是毫无用处的。但是加上\Uand\L就可以得到每个字母的大写和小写; IE,{F,f}{O,o}{O,o}
  • eval然后就是使用告诉 shell 展开 {的简单问题X,X大括号序列。

答案3

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

编辑:我不知道为什么,但这个解决方案是真的与 @Joeseph R 的 perl 解决方案相比,速度更快。它在不到 0.3 秒的时间内运行“Supercalifragilisticexpialidocious”!

这是我的破解方法:

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

运行它:

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

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

答案4

我根据最佳答案编写了一些简单的函数,这些函数将以所需的格式进行输出。

to_lower () 
{ 
    tr '[[:upper:]]' '[[:lower:]]' <<< $@
}
to_upper () 
{ 
    tr '[[:lower:]]' '[[:upper:]]' <<< $@
}
generate_permutations () 
{ 
    local perm="$@";
    perl -e '@foo = split(//, $ARGV[0]);foreach my $c (@foo){print "$c $c\n";}' ${perm} | while read l u; do
        echo "{$(to_lower ${l}),$(to_upper $u)}";
    done | tr -d '\n';
    echo
}

用法/示例:

$ generate_permutations foobar
{f,F}{o,O}{o,O}{b,B}{a,A}{r,R}

相关内容