Reputation: 5211
I'm writing a simple script to generate all combinations of a and b of a given length (say 10). I want to be able to do this on a command line (I know this is fairly easy if I just put everything in a bash script file and execute it). However, I was wondering if it's possible to do without any extra files. Here's what I have so far:
n=10;
for i in `seq 1 1 $n`; do
echo "for a$i in {a..b}; do ";
done;
echo -n "echo ";
for i in `seq 1 1 $n`; do
echo -n '$'"a$i"; done;
echo;
for i in `seq 1 1 $n`; do
echo "done;";
done
(I formatted the code for readability, but it's actually all on one line run from a prompt)
This gives me the following output:
for a1 in {a..b}; do
for a2 in {a..b}; do
for a3 in {a..b}; do
for a4 in {a..b}; do
for a5 in {a..b}; do
for a6 in {a..b}; do
for a7 in {a..b}; do
for a8 in {a..b}; do
for a9 in {a..b}; do
for a10 in {a..b}; do
echo $a1$a2$a3$a4$a5$a6$a7$a8$a9$a10
done;
done;
done;
done;
done;
done;
done;
done;
done;
done;
which is just fine. If I copy that and paste it back on the command line, it works like a charm and gives me the result.
The question is how do I do this with just the initial script, without copy-pasting and without redirecting anything to files.
I've tried sticking $( ) around the script, but that gives me "No command 'for' found'", since it's not really a command but a bash builtin. I've tried putting eval somewhere before this, but I just keep getting more errors. I'm a bit stuck, so any help would be greatly appreciated.
(Btw, just to reiterate, I'm doing this more or less to just learn bash more -- that's why I don't want to redirect the output to a file and then execute that file. I know how to do that part, but I don't know how to just do it from command line)
Upvotes: 7
Views: 11737
Reputation: 359955
You can do for i in $(seq $n)
instead of seq 1 1 $n
.
You can do for ((i=1; i<=$n; i++))
and avoid calling an external utility.
You can do this (slightly hacky with only one loop):
$ a=A; b=B; n=4; s=''; for ((i=1;i<=n;i++)); do s+="{$a..$b}"; done; eval echo "''" $s"$'\n'"
or this (highly hacky without any loops):
$ a=A; b=B; n=4; eval echo "''" $(printf "{$a..$b}%.0s" $(eval echo "{1..$n}"))"$'\n'"
Either one will get you this:
AAAA
AAAB
AABA
AABB
ABAA
ABAB
ABBA
ABBB
BAAA
BAAB
BABA
BABB
BBAA
BBAB
BBBA
BBBB
Upvotes: 2
Reputation: 17117
You need to use an eval, $() gives you a string.
eval $( echo echo foo )
Another option is to stick into a subshell and pipe it to a bash:
(echo echo foo) | /bin/bash
Upvotes: 23