Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I define a list in bash like this:

list="element1 element_2 my_element_3 element04"

and I want to do a loop where I iterate through all possible pair combinations. In Perl, I would use a while/foreach with a shift on the list like this:

while (my $element1 = shift (@list)) {
  foreach my $element2 (@list) {
      print "$element1 - $element2\n";
  }
}

I don't want the same element in the pair and don't care about the order of the pairs, so if the list is "A B C", the result should be:

A - B
A - C
B - C

How can I do the equivalent in bash?

share|improve this question
up vote 7 down vote accepted

The simplest approach seems to be to use positional parameters.

set -- value1 value2 "value with spaces"
for a; do
    shift
    for b; do
        printf "%s - %s\n" "$a" "$b"
    done
done
share|improve this answer
    
hmmmm, just to clarify, I don't want the same element in the pair and don't care about the order of the pairs, I've edited my question now. – 719016 Aug 2 '11 at 13:12
    
I just saw the shift in your original question as well. Updated answer to match. – jw013 Aug 2 '11 at 13:21

Another way to think about your problem is: if you had (i,j) indexes for each item in your list, you would only be interested in the set of items above (or below) the diagonal (ie, where i>j).

If you did want all combinations, then you only have to test where i!=j.

I wanted to do a similar thing: generate all possible orderings of 4 items. For loops nested to a depth of 4 would not be very pretty, and an elegant conditional didn't come to mind, but this solution did:

$ for combo in  {en,fa,sp,ru}{en,fa,sp,ru}{en,fa,sp,ru}{en,fa,sp,ru}; do echo $combo; done | egrep -v 'en.*en|fa.*fa|sp.*sp|ru.*ru' 
enfaspru
enfarusp
enspfaru
ensprufa
enrufasp
enruspfa
faenspru
faenrusp
faspenru
faspruen
faruensp
faruspen
spenfaru
spenrufa
spfaenru
spfaruen
spruenfa
sprufaen
ruenfasp
ruenspfa
rufaensp
rufaspen
ruspenfa
ruspfaen
share|improve this answer

dump the output to standard out, pipe to sort -u

share|improve this answer

You must log in to answer this question.

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