Como iterar sobre todas as combinações de pares em uma lista no bash?

5

Eu defino uma lista no bash assim:

list="element1 element_2 my_element_3 element04"

e eu quero fazer um loop onde eu percorro todas as combinações de pares possíveis. Em Perl, eu usaria um while / foreach com uma mudança na lista como esta:

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

Eu não quero o mesmo elemento no par e não me importo com a ordem dos pares, então se a lista é "A B C", o resultado deve ser:

A - B
A - C
B - C

Como posso fazer o equivalente em bash?

719016
fonte

Respostas:

9

A abordagem mais simples parece ser usar parâmetros posicionais.

set -- value1 value2 "value with spaces"
for a; do
    shift
    for b; do
        printf "%s - %s\n" "$a" "$b"
    done
done
jw013
fonte
hmmmm, só para esclarecer, não quero o mesmo elemento no par e não me importo com a ordem dos pares, editei minha pergunta agora.
719016
Eu também vi a mudança na sua pergunta original também. Resposta atualizada para corresponder.
jw013
1

Outra maneira de pensar sobre o seu problema é: se você tivesse (i, j) índices para cada item em sua lista, você estaria interessado apenas no conjunto de itens acima (ou abaixo) da diagonal (ou seja, onde i & gt; j) .

Se você quisesse todas as combinações, então você só tem que testar onde eu! = J.

Eu queria fazer uma coisa semelhante: gerar todos os pedidos possíveis de 4 itens. For loops aninhados a uma profundidade de 4 não seriam muito bonitos, e uma condicional elegante não veio à mente, mas essa solução fez:

$ 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
toddkaufmann
fonte
-2

despejar a saída para saída padrão, canalizar para classificar -u

Stu
fonte