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 percorrer todas as combinações de pares possíveis. Em Perl, eu usaria um while / foreach com um turno na lista assim:

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, portanto, se a lista for "A B C", o resultado deve ser:

A - B
A - C
B - C

Como posso fazer o equivalente em bash?

    
por 719016 02.08.2011 / 14:51

3 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
    
por 02.08.2011 / 15:06
1

Outra maneira de pensar sobre o seu problema é: se você tivesse (i, j) índices para cada item da sua lista, 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 algo 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 esta 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
    
por 24.03.2014 / 09:24
-2

despeja a saída para saída padrão, canalize para classificar -u

    
por 02.08.2011 / 15:25

Tags