0
votes

Comment irait-je en boucle sur des paires de valeurs sans répétition à bash?

J'utilise un programme particulier qui me demanderait d'examiner des paires de variables dans un fichier texte en spécifiant les paires à l'aide d'indices.

Par exemple: P>

gcta  --reml-bivar 1 3 --grm test  --pheno test.phen  --out test
gcta  --reml-bivar 1 4 --grm test  --pheno test.phen  --out test


3 commentaires

Veuillez ajouter une entrée d'échantillon (aucune description, aucune image, sans liens) et votre sortie souhaitée pour cette entrée d'échantillon à votre question (pas de commentaire).


@Cyrus je l'ai fait.


Veuillez poster deux colonnes dans un fichier texte exemple fichier d'entrée et comment chaque paire ressemblerait. Qu'est-ce que "chaque paire sans répétition" ressemble et signifie?


5 Réponses :


0
votes

1 et 2 correspondrait aux valeurs des deux premières colonnes d'un fichier texte. P>

chaque paire sans répétition p>

Parcourons ce processus: P>

  1. Nous répétons la première colonne du fichier fois la longueur du fichier li>
  2. Nous répétons chaque valeur (chaque ligne) de la deuxième colonne du fichier fois la longueur du fichier li>
  3. Nous rejoignons les colonnes répétées -> Nous avons toutes les combinaisons li>
  4. Nous devons filtrer les "répétitions", nous pouvons simplement rejoindre le fichier avec le fichier d'origine et filtrer les colonnes répétées li>
  5. Nous obtenons donc chaque paire sans répétitions. Li>
  6. Ensuite, nous viens de lire la ligne de fichier par ligne. LI> ol>

    Le script: p>

    1 b
    1 c
    1 d
    2 a
    2 c
    2 d
    3 a
    3 b
    3 d
    4 a
    4 b
    4 c
    

0 commentaires

0
votes

Si je vous comprends correctement et que vous n'avez pas besoin de paires ressemblent à '1 1', '2 2', ... et '1 2', '2 1' ... essayez ce script

#!/bin/bash

for i in $(seq 1 49);
do
    for j in $(seq $(($i + 1)) 50);
    do gcta --reml-bivar "$i $j" --grm test --pheno test.phen --out test
done;

done;


0 commentaires

0
votes

Étant donné que vous ne nous avez pas montré une entrée d'échantillon, nous devons simplement deviner, mais si votre entrée est la liste des numéros (extraits d'un fichier ou autre), voici une approche:

$ awk -f permutations.awk <<< '1 2 3 4'
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 2 3
4 1 3 2
4 2 1 3
4 2 3 1
4 3 1 2
4 3 2 1


4 commentaires

Salut merci, c'est extrêmement utile! Je me demandais s'il existe un moyen d'imprimer une série de chiffres pour nourrir cette fonction que vous avez créée, au lieu de taper '1 2 3 4 5 ... 50'? Merci beaucoup. @Ed Morton


SEQ 50 . Voir Stackoverflow.com/help/someone-answers pour quoi faire ensuite.


Salut, j'ai essayé awk -f combinaisons.awk <<< 'SEQ 50' mais a été retourné à 50 SEQ. Y a-t-il quelque chose que je ne fais pas bien?


Pour exécuter une commande, vous utilisez des backtsks, pas des guillemets simples, ni même mieux $ (...) (voir MYWIKI.WOOLEDGE.org/BashFAQ/082 ). Essayez awk -f combinaisons.awk <<< $ $ (SEQ 50) ou awk -f combinaisons.awk <<< (SEQ 50)



0
votes
    #!/bin/bash

    #set the length of the combination depending the 
    #user's choice 

    eval rg+=({1..$2})

    #the code builds the script and runs it (eval)

    eval `
    #Character range depending on user selection
    for i in ${rg[@]} ; do
    echo "for c$i in {1..$1} ;do " 
    done ;


    #Since the script is based on a code that brings 
    #all possible combinations even with duplicates - 
    #this is where the deduplication 
    #prevention conditioning set by (the script writes           
    #the conditioning code)


    op1=$2
    op2=$(( $2 - 1 ))
    echo -n "if [ 1 == 1 ] "

    while [ $op1 -gt 1 ]  ; do
    echo -n  \&\& [ '$c'$op1 != '$c'$op2 ]' '
    op2=$(( op2 -1 )
    if [ $op2 == 0 ] ; then  
            op1=$(( op1 - 1 ))
            op2=$(( op1 - 1 ))
    fi
    done ;

    echo  ' ; then'
    echo -n "echo "

    for i in ${rg[@]} ; 
    do
    echo -n '$c'$i
    done ;

    echo \;
    echo fi\;

    for i in ${rg[@]} ; do
    echo 'done ;'
    done;`

    example:               range       length
    $ ./combs.bash '{1..2} {a..c} \$ \#' 4
    12ab$
    12ab#
    12acb
    12ac$
    12ac#
    12a$b
    12a$c
    12a$#
    12a#b
    12a#c
    12a#$
    ..........

2 commentaires

Alors que ce code peut résoudre la question, , y compris une explication de la manière et pourquoi cela résout le problème aiderait vraiment à améliorer la qualité de la qualité. de votre message et aboutit probablement à plus de votes. N'oubliez pas que vous répondez à la question des lecteurs à l'avenir, pas seulement la personne qui demande maintenant. S'il vous plaît Modifier Votre réponse Pour ajouter des explications et donner une indication de quelles limitations et hypothèses s'appliquent.


Bien désolé pour le manque d'explications (l'anglais n'est pas ma langue maternelle. Pas vraiment le second non plus.) Le script répond à toutes les combinaisons de chiffres, lettres sans caractères à deux chiffres.J'ai ajouté des commentaires dans le script et j'adorerais pour les commentaires



0
votes
      #!/bin/bash
      len=$2
      eval c=($1)
      per()
      {
      ((`grep -Poi '[^" ".]'<<<$2|sort|uniq|wc -l` < $((len - ${1}))))&&{ return;}
      (($1 == 0))&&{ echo $2;return;}
      for i in ${c[@]} ; do
      per "$((${1} - 1 ))" "$2 $i"
      done
      }
      per "$2" ""

      #example
      $ ./neto '{0..3} {a..d} \# \!'  7
      0 1 2 3 a b c
      0 1 2 3 a b d
      0 1 2 3 a b #
      0 1 2 3 a b !
      0 1 2 3 a c b
      0 1 2 3 a c d
      0 1 2 3 a c #
      0 1 2 3 a c !
      0 1 2 3 a d b
      ...

2 commentaires

Ceci est un code court et rapide qui permet à l'utilisateur de déterminer la gamme de caractères.


Bienvenue à cela. Ajout d'une explication dans vos réponses aide les autres utilisateurs à comprendre le code.