I'm trying to find combinations of characters that fit a (c)v pattern for up to n syllables, and so started by using expansion like echo {,p,t}{a,i} for all the possibilities for one syllable (using just 2 letters for readability). In order to get more syllables, all I could think of was expanding it for each syllable like echo {{,p,t}{a,i},{,p,t}{a,i}{,p,t}{a,i}} (ie, 'all the one syllable combinations then all the two syllable combinations'). Is there a better way to extend this to n syllables, so that I can type something kinda like echo {,p,t}{a,i}*{1..3} for all the 1, 2, and 3 syllable expansions(and so on)?

  • 1
    Bash seems to be a very inadequate tool for what you're trying to do. Have you considered not using a shell language, which is really meant to serve computer administration tasks, for problems like generating strings of syllables? Oct 1 at 22:37
  • I don't know any shell languages, I am relatively new to the command line; that's why I started with my problem rather than how I've tried to solve it so far. I presume that means that there isn't a repeat n times format for bash expansion? Does that just not come up often enough to be considered a useful feature?
    – guest4308
    Oct 1 at 23:18
  • Bash scripting is a shell language. That's why I asked you to consider whether you really want to do it in such an ill-suited language! I don't think there's a direct way, no. When would that problem ever come up in administrating computers? That's what bash is for: starting other programs and allowing for automation of simple Administrator tasks. You could possibly hack something together with recursive replacements in a generated list, but that is hard to program, harder to understand and unnecessarily error-prone. Question: do you know any other programming languages? Oct 1 at 23:22
  • ahh, I see. I thought shell language would mean making a .sh file and running it; that means a .sh file is basically for running each line in bash? I have used a number of other programming languages, but I defaulted to bash since I can just open up the terminal and just run things to get answers to my questions, where I'd have to get something else to run other code. also, if repeating isn't helpful, why is brace expansion helpful? aren't they almost the same thing?
    – guest4308
    Oct 1 at 23:46
  • 1
    The "I need to get the tools I need installed" argument is a bit flimsy: every significant desktop Linux these days comes with interpreters for multiple languages installed. Try running python or perl! Installing Lua, a C++ compiler or JavaScript runtime is also but a single command away. And just like your she'l script is just your shell being called with the file as argument (that's why they have #!/bin/bash at the beginning! It specifies which program to run with the file), so is e.g. a python script just being executed when you run python scriptname.py. No magic involved! Oct 2 at 0:14

3 Answers 3


You could do something like this

Bash, 165 bytes

printf '{'
while [ "$i" -gt 0 ] ; do
  (( i-- ))
  printf '%s' "$con,"
printf '}'

eval echo "$(f 6 '{,p,t}{a,i}')"

Try it online!

  • Lol love that you used the code golf template Oct 2 at 0:05
  • 1
    It served the purpose I needed it to 😊
    – bxm
    Oct 2 at 0:08
  • 1
    And I honestly think that's one valid way of how solving this kind of problem in bash could be considered — a mental sport, but not something you'd want to see for production usage Oct 2 at 0:17
  • I love it :). (Useful to try it without eval :).)
    – K-attila-
    Oct 2 at 11:35

Zsh, 73 bytes

c=('' p t) v=(a i) r=({1..4})
(){echo ${(e)@}} '${(el['$^r'*6][$^c$^v])}'

Try it online!

Unrolling it:

$ c=( '' p t ) v=( a i ) r=( {1..4} )
$ echo $c$v
p ta i
$ echo $^c$^v
a i pa pi ta ti

With $^c instead of $c, arrays are expanded a bit like in brace expansion.

$ echo ${(l[12][$^c$^v])}

We expand nothing (that parameter expansion has no parameter) using the left padding operator, here padding with $^c$^v strings to a length of 12 (twice the length of $^c$^v string).

$ echo ${(el[12][$^c$^v])}
aa ai apa api ata ati ia ii ipa ipi ita iti paa pai papa papi pata pati pia pii pipa pipi pita piti taa tai tapa tapi tata tati tia tii tipa tipi tita titi

If we add the e parameter expansion flag, the expansions in the result are evaluated/expanded.

So all we need to do is generate those for paddings of 6, 12, ... n*6.

$ echo '${(el['$^r'*6][$^c$^v])}'
${(el[1*6][$^c$^v])} ${(el[2*6][$^c$^v])} ${(el[3*6][$^c$^v])} ${(el[4*6][$^c$^v])}

If we can put those words in an array, we can apply the e flag to it to expand the result. For that we use an anonymous function, and pass those words as arguments, and they'll be available in the $@ aka $argv array within.


Usind the most of your code/logic.

ksh, 95 bytes, no evil eval :)

for ((i=1; i<=n; i++)) {
    printf -v x '{,p,t}{a,i}%.0s' {1..$i}
    printf '%s\n' $x

If your ksh implementation don't support printf -v x, replace by x=$(printf ...)

Try it online!

  • Note that assumes recent versions of ksh93u+m for printf -v. -v is not really necessary in ksh93 since you can do x=${ printf ....;} instead. Oct 2 at 8:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .