IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

intersection liste script bash


Sujet :

Shell et commandes GNU

  1. #1
    Membre éclairé
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Par défaut intersection liste script bash
    Bonjour à tous,
    J'ai ecris ce petit script bash :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #!/bin/sh
     
    "ma commande a executer > output.bam"
    liste1=`cat "output.bam" | cut -f 3 | cut -f1 -d ';' | sort -u`
     
    "ma commande 2 a executer > output2.bam"
    liste2=`cat "output2.bam" | cut -f 3 | cut -f1 -d ';' | sort -u`
    Je cherche maintenant à regarder la valeur de l'intersection de mes deux listes, j'ai donc fait comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    value=`comm -12 $liste1 $liste2 | uniq | wc -l`
    Mais cela ne fonctionne pas, j'obtiens l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    comm: opérande supplémentaire «FBgn0000057»
    Saisissez «*comm --help*» pour plus d'informations.
    FBgn0000057 etant un element de ma liste1 ....
    Quelqu'un aurait une idée ?
    Merci d'avance

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    Bonjour,

    comm opère sur des fichiers, et vu que tu as déjà deux fichiers temporaires, on ne va pas en ajouter; mais ce ne sera pas aussi simple :
    il va falloir utiliser un descripteur de fichier supplémentaire (càd, en plus de stdin, stdout et stderr)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while read line1; do read <&3 line2; test "$line1" = "$line2" && echo "$line1"; done <fichier1 3<fichier2
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre éclairé
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Par défaut
    Merci pour ta réponse,
    je suis débutante et je ne comprends pas tout ce que tu fais :
    - à quoi correspond : - que fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test "$line1" = "$line2" && echo "$line1"
    et enfin,
    - que fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    done <fichier1 3<fichier2
    ?

    Merci d'avance pour tes explications

  4. #4
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    on va commencer par la fin, car en fait c'est le début de tout
    et enfin,
    - que fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    done <fichier1 3<fichier2
    pour le fichier1, regarde ceci : Comment lire un fichier
    le fichier2, lui, est rédirigé vers le descripteur de fichier n° 3
    il y a normalement 3 descripteur de fichiers
    • stdin : 0 : l'entrée standard (typiquement le clavier)
    • stdout : 1 : la sortie standard (typiquement l'écran)
    • stderr : 2 : la sortie d'erreur (typiquement l'écran aussi, mais distinct de stdout, pour continuer de s'afficher à l'écran lorsque stdout est redirigé)
    on peut en ajouter arbitrairement. Ici j'utilise le n°3.
    c'est nécessaire car l'entrée standard de la boucle while est prise par la redirection du fichier1.

    - à quoi correspond :
    read va lire la redirection du descripteur de fichier n°3 vers lequel on a redirigé le fichier2.

    - que fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test "$line1" = "$line2" && echo "$line1"
    bah!? c'est un test ! s'il est vrai (&&) l'action suivante est exécutée.
    j'aurais pu écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if test "nanana"; then echo "bla bla"; fi
    mais comme il n'ya qu'une action, j'utilise une forme courte.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Membre éclairé
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Par défaut
    Merci pour ces explications.
    Mais alors je peux donner en entrée $liste1 et $liste2 ou il fait que je crée des fichiers temporaire ?

  6. #6
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    ah, oui! dis donc, j'avais zappé ce problème

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    exec 3<<eof
    $(cut -f 3 output.bam | cut -f1 -d ';' | sort -u)
    eof
    exec 4<<eof
    $(cut -f 3 output2.bam | cut -f1 -d ';' | sort -u)
    eof
     
    while read <&3 line1
    do read <&4 line2
       test "$line1" = "$line2" && echo "$line1"
    done
    non mais (j'ai un peu galéré, c'est pas du bash )

    deux choses encore:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ echo a b c | cut -f 3
    a b c
    il faut un délimiteur!

    les commandes cut/sort étant les même utilise une fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    traitement() { cut -d ' ' -f3 "$1" | cut -d';'  -f1 | sort -u;}
    exec 3<<eof
    $(traitement output.bam)
    eof
    ...
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Membre éclairé
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Par défaut
    Merci pour ton aide,
    j'ai un petit problème, cela ne me retourne rien, or, si j'ai bien compris, echo "$line1", devrait me retourner la ligne si la ligne en question se trouve dans les deux fichiers ...
    Suite à ce que tu m'as dit, j'ai fait comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #!/bin/sh
     
    "ma commande a executer > output.bam"
    "ma commande 2 a executer > output2.bam"
    traitement() { cut -d ' ' -f3 "$1" | cut -d';'  -f1 | sort -u;}
     
    exec 3<<eof
    $(traitement output.bam)
    eof
    exec 4<<eof
    $(traitement output2.bam)
    eof
     
    while read <&3 line1
    do read <&4 line2
       test "$line1" = "$line2" && echo "$line1"
    done
    les fichiers .bam sont du type :
    dme_pi_899_27_1 - FBgn0261338;FBtr0302254;CG42623-RA;966 262
    dme_pi_942_27_5 - FBgn0085442;FBtr0301851;NKAIN-RJ;2329 2139

    Ai je fais une erreur ?

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Je viens de tester chez moi et tout marche bien

    Sous quelle distrib es-tu ?
    Quel shell ?
    sh est un lien symbolique ? Si oui vers quel shell (readlink -f /bin/sh) ?

  9. #9
    Membre éclairé
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Par défaut
    ha oui effectivement c'est
    et non
    Comment puis je modifier le script de façon à ce qu'il retourne le nombre d'elements en commun dans mes deux listes ?

  10. #10
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut

    j'ai testé avec succés sous ash, dash, bash, mksh, pdksh, ksh93.
    mais bon si ça fonctionne sous ash, c'est que c'est correct.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Membre éclairé
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Par défaut
    J'ai trouvé toute seule finalement !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #!/bin/bash
     
    bowtie -v 0 -a --best --strata --nofw --quiet transcript_liste639 -f shuffle_NR_banque_pi_02h_truncated.fasta > output.bam
    bowtie -v 0 -a --best --strata --nofw --quiet transcript_liste639 -f shuffle_NR_banque_pi_02h_truncated.fasta > output2.bam
    traitement() { cut -f3 "$1" | cut -d';'  -f1 | sort -u;}
     
     
    exec 3<<eof
    $(traitement output.bam)
    eof
    exec 4<<eof
    $(traitement output2.bam)
    eof
    value=0 
    while read <&3 line1
    do read <&4 line2
       test "$line1" = "$line2" && value=$(($value+1))
    done
    echo $value
    Merci pour votre aide

  12. #12
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    ah, alors en bash :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/bin/bash
    trans="transcript_liste639"
    shuf="shuffle_NR_banque_pi_02h_truncated.fasta"
    traitement() {
       bowtie -v 0 -a --best --strata --nofw --quiet "$trans" -f "$shuf" | cut -d' ' -f3 | cut -d';'  -f1 | sort -u
    }
     
     
    while read line1
    do read -u3 line2
       test "$line1" = "$line2" && ((compte++))
    done < <(traitement) 3< <(traitement)
    echo $compte
    mais quelque chose ne va pas : les commandes bowtie traitent les mêmes fichiers; elles auront donc le même résultat !?
    la création des fichiers .bam est elle obligée ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  13. #13
    Membre éclairé
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Par défaut
    mais quelque chose ne va pas : les commandes bowtie traitent les mêmes fichiers; elles auront donc le même résultat !?
    la création des fichiers .bam est elle obligée ?
    Effectivement les commandes bowtie ont ici le meme résultat, c'etait uniquement pour tester !!

    une petite question : a quoi correspond u3 dans :
    J'ai une nouveau problème, en fait je souhaite regarder l'intersection entre un fichier.txt et le resultat de ma commande (avec cut sort uniq).
    J'ai donc fait ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #!/bin/bash
     
    comptage() { cut -f3 "$1" | cut -d';'  -f1 | sort -u | wc -l;}
     
    traitement() { cut -f3 "$1" | cut -d';'  -f1 | sort -u;}
     
    intersection(){ 
    exec 3<<eof
    $(traitement $2)
    eof
    value=0 
    while read line1
    do read <&3 line2
       test "$line1" = "$line2" && value=$(($value+1))
    done < $1
    echo $value
    }
     
     
    bowtie -v 0 -a --best --strata --nofw --quiet transcript_liste639 -f banque_pi_02h_truncated.fasta > v0_test.bam
    v0=$(comptage v0_test.bam) 
     
     
    bowtie -v 0 -a --best --strata --nofw --quiet transcript_liste639 -f banque_pi_02h_truncated.fasta > liste639_v0_test.bam
    $inter_v0=$(intersection sorted_FBgn_expressed_02h.txt v0_test.bam)
     
    echo $v0	$inter_v0
    Mais cela me retourne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ./test.sh: ligne 32: =0 : commande introuvable
    1941
    fichier .txt du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    FBgn0261338
    FBgn0085442

  14. #14
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    [...]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     -u fd             lire depuis le descripteur de fichier FD plutôt que l'entrée standard
    read $2 devrait lire quoi ?
    $inter_v0= non : inter_v0=.
    cut -f3 ne fonctionnera toujours pas sans séparateur.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  15. #15
    Membre éclairé
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Par défaut
    J'ai fait ceci : mais cela me renvoi une intersection nulle alors que ce n'est pas le cas ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #!/bin/bash
     
    comptage() { cut -f3 "$1" | cut -d';'  -f1 | sort -u | wc -l;}
     
    traitement() { cut -f3 "$1" | cut -d';'  -f1 | sort -u;}
     
    intersection(){ 
    exec 3<<eof
    $(traitement $2)
    eof
    value=0 
    while read line1 # censé lire le fichier .txt
    do read <&3 line2 # censé lire ce que contient la 3é colonne du fichier .bam
       test "$line1" = "$line2" && value=$(($value+1))
    done < $1
    echo $value
    }
     
     
    bowtie -v 0 -a --best --strata --nofw --quiet transcript_liste639 -f banque_pi_02h_truncated.fasta > v0_test.bam
    v0=$(comptage v0_test.bam) 
     
    inter_v0=$(intersection sorted_FBgn_expressed_02h.txt v0_test.bam)
     
    echo $v0	$inter_v0

  16. #16
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    il serait utile que tu nous affiches quelques lignes représentatives des fichiers, ou, s'ils ne comportent pas de secrets, et qu'ils ne sont pas trop volumineux, que tu les mettes en pièces jointes; parce que, comme ça, le script devrait fonctionné, donc, ça vient peut-être des fichiers, ou d'un code qui n'extrait pas les données nécessaires.

    l'usage d'une fonction pour trouver l'intersection est inutile (pas le code ! seulement le fait qu'il soit dans un fonction )
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  17. #17
    Membre éclairé
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Par défaut
    donc alors, les fichiers de sortie de bowtie :
    v0_test.bam :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    dme_pi_899_27_1	-	FBgn0261338;FBtr0302254;CG42623-RA;966
    dme_pi_942_27_5	-	FBgn0085442;FBtr0301851;NKAIN-RJ;2329
    dme_pi_942_27_5	-	FBgn0085442;FBtr0305056;NKAIN-RK;4873
    dme_pi_1907_28_1	-	FBgn0040010;FBtr0332632;CG17493-RD;5997
    fichier:
    sorted_FBgn_expressed_02h.txt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FBgn0261338
    FBgn0085442
    FBgn0040010
    Ensuite, si j'ai mit intersection dans une fonction, c'est parce que je dois faire cette fonction sur beaucoup de fichier, donc je trouve cela plus pratique plutôt que de mettre ce code à chaque fois ...

  18. #18
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    si j'ai mit intersection dans une fonction, c'est parce que je dois faire cette fonction sur beaucoup de fichier, donc je trouve cela plus pratique plutôt que de mettre ce code à chaque fois ...
    peut-être une boucle for sur les fichiers...
    ?


    le script fonctionne très bien avec les fichiers donnés (le script affiche 1), et je comprend l'absence de délimiteur pour le premier cut

    peut-être qu'avec une trace de l'exécution tu verras là où ça pêche...
    sous le shebang, ajoute ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    exec 2>/tmp/traitement.bam.log
    set -x
    tu pourras, après exécution, lire le fichier /tmp/traitement.log, et voir ce qui n'est pas correctement exécuté
    ...
    ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    $ cat > v0_test.bam                                                                                 
    dme_pi_899_27_1 -       FBgn0261338;FBtr0302254;CG42623-RA;966
    dme_pi_942_27_5 -       FBgn0085442;FBtr0301851;NKAIN-RJ;2329
    dme_pi_942_27_5 -       FBgn0085442;FBtr0305056;NKAIN-RK;4873
    dme_pi_1907_28_1        -       FBgn0040010;FBtr0332632;CG17493-RD;5997
    $ cat > sorted_FBgn_expressed_02h.txt                                                               
    FBgn0261338
    FBgn0085442
    FBgn0040010
    $ unset value
    $ traitement() { cut -f3 "$1" | cut -d';'  -f1 | sort -u;}
    $ intersection(){
    exec 3<<eof
    $(traitement $2)
    eof
    while read line1; do read <&3 line2; test "$line1" = "$line2" && ((value++)); done < $1; echo $value; }
    $ set -x; intersection sorted_FBgn_expressed_02h.txt v0_test.bam; set +x
    + intersection sorted_FBgn_expressed_02h.txt v0_test.bam
    + exec
    ++ traitement v0_test.bam
    ++ sort -u
    ++ cut '-d;' -f1
    ++ cut -f3 v0_test.bam
    + read line1
    + read line2
    + test FBgn0261338 = FBgn0040010
    + read line1
    + read line2
    + test FBgn0085442 = FBgn0085442
    + (( value++ ))
    + read line1
    + read line2
    + test FBgn0040010 = FBgn0261338
    + read line1
    + echo 1
    1
    + set +x
    $
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  19. #19
    Membre éclairé
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Par défaut
    Je pense que le problème vient du parcours, qui n'est pas dans le bon ordre ..
    en effet, on voit bien que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FBgn0261338
    FBgn0085442
    FBgn0040010
    sont aussi dans le fichier .bam, l'intersection devrait être de 3, or, la, elle est de 1 ...
    en fait il compare pas toutes les combinaisons possibles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    + test FBgn0261338 = FBgn0040010
    + test FBgn0085442 = FBgn0085442
    + test FBgn0040010 = FBgn0261338
    Peut on modifier cela ?

  20. #20
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    le problème est-il que l'une des entrées n'est pas triée,
    ou faudrait-il de, toutes manières, tester chaque ligne de l'un des fichiers sur l'ensemble de l'autre fichier ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Requête POST dans un script bash
    Par desperado dans le forum Linux
    Réponses: 4
    Dernier message: 11/12/2007, 22h38
  2. Réponses: 21
    Dernier message: 29/09/2005, 19h33
  3. Script bash : Pb avec sed
    Par fred64 dans le forum Linux
    Réponses: 3
    Dernier message: 19/08/2005, 11h24
  4. Scripts bash : requêtes sql
    Par milka dans le forum Linux
    Réponses: 3
    Dernier message: 17/08/2005, 10h59
  5. Problème script Bash
    Par Sphost dans le forum Linux
    Réponses: 10
    Dernier message: 26/07/2005, 09h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo