bashshellpermutationbrace-expansion

Generate all permutations of up to `n` letters


I'd like to generate all permutations of letters up to length n

For example, for the argument 2 I'd like obtain a list like

a
aa
..
az
...
z
za
..
zz

I tried using a for loop to generate n increasingly larger brace expansions by repeating {a..z} ^1 and appending it to a variable. But this doesn't seem to work.

OUT=""

# loop from 1 to first argument
for ((i=1; i<=$1; i++))
do
    OUT+=$(echo $(printf '{a..z}%.0s' {1..$i}))
done

OUT=$(echo $OUT | sort)

echo $OUT

Solution

  • Chained brace expansions don't scale well. You're better off with a function like this:

    # Usage: perms n [prefix]
    perms() {
      if (($1 < 1)); then
        return
      fi
    
      for pfix in "$2"{a..z}; do
        printf '%s\n' "$pfix"
        perms $(($1 - 1)) "$pfix"
      done
    }
    
    $ perms 2
    a
    aa
    ab
    ac
    ...
    

    But if you insist on it, this is how you should do it:

    # Usage: perms n
    perms() {
      printf -v brace_exp '{a..z}%*s' $(($1 - 1))
      brace_exp=${brace_exp// /'{,{a..z}}'}
      eval "printf '%s\n' $brace_exp"
    }