Problème argument pour grep et boucle for

Résolu
ONI -  
dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour,
Je travaille sous unix (plus précisément sur le terminal sur un mac) pour modifier des fichiers texte contenant des données issues de GenBank (des données de séquençage ADN... enfin peu importe).
Mon problème est le suivant :
- j'ai un fichier texte de la forme :

>GENRE1espèces1|(plein d'infos pas utiles)|co1(nom du gène)
acgtcgcgatcgagagatctctagagctctgagatcgagct
acgatatatgcgcgacgatagatatcggatcg
......
>GENRE1espèces2|(plein d'infos pas utiles)|co1
......
>GENRE2espèces1|(plein d'infos pas utiles)|co1
......

Le saut de ligne est le même dans le fichier. (je vous ai évité le nom de genre et d'espèce des bestioles pour un souci de clarté)

Et j'aimerais créer un fichiers (à partir de celui-la) pour chaque GENRE répertoriant toutes les séquences (acgtgtg...) appartenant à ce genre et donc obtenir plusieurs fichiers du type :

GENRE1
séquences1-acgtgagtgc
séquences2-accggggtgtgt
........

Et dernière chose j'aimerais ajouter une même dernière ligne à tous ces fichiers, cette ligne, contenu dans un fichier (donc avec une seule ligne), étant une séquence de référence pour le genre.

Étant débutant en programmation shell unix, je pense qu'il faudrait utiliser une voir plusieurs boucles for ainsi que des grep à tout va mais c'est dans l'argumentation propre des lignes de commandes que je bute.

J'espère avoir été assez clair, merci d'avance de vous prendre la tête avec moi ;).

41 réponses

  • 1
  • 2
  • 3
Résumé de la discussion

Il s'agit de générer un fichier par genre contenant toutes les séquences associées et d'ajouter à la fin une ligne de référence issue d'un fichier séparé. Une approche pratique consiste à utiliser awk avec des séparateurs [>&|] pour router chaque en-tête >GENRE vers un fichier nommé d'après le genre, puis écrire les séquences et insérer la référence via une variable. Des solutions évitent l'explosion du nombre de fichiers ouverts en fermant systématiquement les flux après écriture et permettent des vérifications, comme compter les genres et prévenir les erreurs liées aux limites système.

Bobot (l'IA à votre service)
  1. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    hello
    quelque chose comme ça ?
    $ cat f1
    >GENRE1espèces1|(plein d'infos pas utiles)|co1(nom du gène)
    acgtcgcgatcgagagatctctagagctctgagatcgagct
    acgatatatgcgcgacgatagatatcggatcg
    ......
    >GENRE1espèces2|(plein d'infos pas utiles)|co1
    xxxxx
    ......
    >GENRE2espèces1|(plein d'infos pas utiles)|co1
    zzzzz
    ...... 
    $ cat f2
    hello world
    $ awk -F"[>|]" '/^>GENRE/ {nom=$2 ; next} {print $0 > nom}' f1 ; ls GEN* | xargs -I{} sh -c 'cat f2 >> {}'
    $ head GENRE*
    ==> GENRE1espèces1 <==
    acgtcgcgatcgagagatctctagagctctgagatcgagct
    acgatatatgcgcgacgatagatatcggatcg
    ......
    hello world
    
    ==> GENRE1espèces2 <==
    xxxxx
    ......
    hello world
    
    ==> GENRE2espèces1 <==
    zzzzz
    ...... 
    hello world
    $ 
    
    1
  2. ONI
     
    Hug,

    Pour f1 et f2 ouais c'est dans ce genre la, mais pour le reste nan ^^.
    En fait, je voudrais tomber à la fin sur un fichier par genre, donc :
    -------------------fichier 1----------------------
    GENRE1
    espèce1 - acgt...
    espèce2 - agtc...
    ...
    hello world
    -------------------fichier 2----------------------
    GENRE2
    espèce1 - atgc...
    espèces2 - agtc...
    ...
    hello world

    etc

    Merci pour ta réponse rapide en tout cas ^^.

    NB: j'ai rien compris à cette ligne de commande XD : $ awk -F"[>|]" '/^>GENRE/ {nom=$2 ; next} {print $0 > nom}' f1 ; ls GEN* | xargs -I{} sh -c 'cat f2 >> {}'
    0
  3. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    comme ça ?
    $ cat f1
    >GENRE1espèces1|(plein d'infos pas utiles)|co1(nom du gène)
    acgtcgcgatcgagagatctctagagctctgagatcgagct
    acgatatatgcgcgacgatagatatcggatcg
    ......
    >GENRE1espèces2|(plein d'infos pas utiles)|co1
    xxxxx
    ......
    >GENRE2espèces1|(plein d'infos pas utiles)|co1
    yyyyyy
    ...... 
    >GENRE2espèces2|(plein d'infos pas utiles)|co1
    zzzzz
    ...... 
    $ 
    $ awk -F"[>|]" '/^>GENRE/ {nom=$2 ; sub("esp.*", "", nom) ; esp=$2 ; sub("G[A-Z]*[1-9]", "", esp) ; next} {print esp " - " $0 > nom}' f1 ; ls GEN* | xargs -i sh -c 'cat f2 >> {}'
    $ 
    $ head GENR*
    ==> GENRE1 <==
    espèces1 - acgtcgcgatcgagagatctctagagctctgagatcgagct
    espèces1 - acgatatatgcgcgacgatagatatcggatcg
    espèces1 - ......
    espèces2 - xxxxx
    espèces2 - ......
    hello world
    
    ==> GENRE2 <==
    espèces1 - yyyyyy
    espèces1 - ...... 
    espèces2 - zzzzz
    espèces2 - ...... 
    hello world
    $ 
    $ 
    
    0
  4. ONI
     
    C'est quasiment ça.

    Me faudrait :
    ==> GENRE1 <==
    espèces1 - acgtcgcgatcgagagatctctagagctctgagatcgagct
    acgatatatgcgcgacgatagatatcggatcg
    ......
    espèces2 - xxxxx
    ......
    hello world

    En fait pas la répétition de "espèce*" parce que :

    >GENRE1espèces1|(plein d'infos pas utiles)|co1(nom du gène)
    acgtcgcgatcgagagatctctagagctctgagatcgagct
    acgatatatgcgcgacgatagatatcggatcg
    ......
    est la séquences entière qui se retrouve coupée en lignes dans mon fichier texte original.

    Après j'espère que mon logiciel d'alignement de séquences (seaview) comprendra ce format. Si c'est pas le cas je pense que remettre la totalité de la séquence sur la mm ligne (mais ça non plus je vois pas comment faire).
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    $ cat f1
    >GENRE1espèces1|(plein d'infos pas utiles)|co1(nom du gène)
    acgtcgcgatcgagagatctctagagctctgagatcgagct
    acgatatatgcgcgacgatagatatcggatcg
    ......
    >GENRE1espèces2|(plein d'infos pas utiles)|co1
    xxxxx
    XXXXXXXX......
    >GENRE2espèces1|(plein d'infos pas utiles)|co1
    yyyyyy
    YYYYYYYY
    >GENRE2espèces2|(plein d'infos pas utiles)|co1
    zzzzz
    ZZZZZZZZZZ
    $ 
    $ awk -F"[>|]" '/^>GENRE/ {nom=$2 ; sub("esp.*", "", nom) ; esp=$2 ; sub("G[A-Z]*[1-9]", "", esp) ; x=" - " ; next} {print esp x $0 > nom ; x=esp="" }' f1 ; ls GEN* | xargs -i sh -c 'cat f2 >> {}'
    $ 
    $ head GENR*
    ==> GENRE1 <==
    espèces1 - acgtcgcgatcgagagatctctagagctctgagatcgagct
    acgatatatgcgcgacgatagatatcggatcg
    ......
    espèces2 - xxxxx
    XXXXXXXX......
    hello world
    
    ==> GENRE2 <==
    espèces1 - yyyyyy
    YYYYYYYY
    espèces2 - zzzzz
    ZZZZZZZZZZ
    hello world
    $ 
    
    0
  7. ONI
     
    Alors oui c'est ça ^^, par contre je sais pas si ta ligne de commande me créé un fichier pou chaque genre.

    Il y a une autre étape pour faire ça bien.

    Voilà à ce quoi ressemble mon fichier original pour les 3 premières séquences, il y en a un nombre assez important.

    >TRIAENODEStardus|UNKNOWN_000000_CANADA:ONTARIO,WELLINGTON,ELORA,NEARncbi_JF434447|co1
    ttgatctggattactaggaacatctttaagagtaataattcgaactgaattaggttcagt
    aggatcattaattaaaaatgatcaaatttataatgtaatagttactgctcatgcttttat
    tataattttttttatagtaatacctataataattggaggatttggaaattgactaattcc
    tttaatactaagatgtcctgatatagcttttcctcgaataaataatataagattttgatt
    acttccaccatctttaaattttcttttattaagaagattagtggaaagaggaacaggaac
    tggttgaactgtctatcctccacttgcaagaacagtaggacatataggaagttctgtaga
    tttatcaattttttctcttcatatagctggtatctcttctattttaggggctattaattt
    tattactacttgtataagaataaaaccaataggtataaatttagatcaaatacccttatt
    tgtttgatcagttttaattactgcattattacttctcttatctttaccagtcttagccgg
    agctattacaatattattaacagatcgtaatcttaatacatctttttttgaccctgccgg
    gggaggagaccctattttatatcaacatttattt

    >HYDROPSYCHEplacoda|UNKNOWN_000000_CANADA:ONTARIO,WELLINGTON,ELORA,NEARncbi_JF434387|co1
    aacactttacttcatatttggaatttgatccggtcttattggatcttctataagatttat
    tattcgaatagaactaagaactccagatagttttattggcaatgatcaaatttataatgt
    tatcgttacatctcatgcatttattataattttctttatagtaatacccattataatcgg
    aggatttggaaattgactagtccctcttatacttggatcccctgatatagcattccctcg
    aataaacaatctaagattttgatttttacccccatctttaacatttctattattaagaag
    aataactaattcaggagctgggacaggttgaacagtctatccccctttatcatcaaattt
    atctcacgcaggaagatctgttgatttaactattttttcccttcatatagcaggaatttc
    ttctattttaggagcaattaacttcatttctactattataaatataaaatttaaaaattt
    aaattatgaaataattcctcttttcgtctgatctatcttaatcacagctgtattactttt
    actatctttaccagtattggctggagccatcacaatattattaactgatcgtaatcttaa
    tacttctttctttgaccctgcgggagggggagacccaattctatatcaacatttattt

    >CHIMARRAobscura|UNKNOWN_000000_CANADA:ONTARIO,WELLINGTON,ELORA,NEARncbi_JF434187|co1
    aaccttgtattttatttttggcctttgatcaagaatattaggtctatctctaagaatact
    tatccgtttagaacttagaactccaggagctttaattggaaatgatcaaatctttaattc
    tattgtaactgcccatgcatttattataattttttttatagtaatacccatcataattgg
    ggggtttggaaactgattggtcccactaatactaggagcaccagacatagccttccctcg
    aataaataatataagattttgatttttgcccccttcattgttctttcttttattcagaat
    acttatagataatgggactggaacaggatggaccgtttacccccccctctctgcaaatat
    ttcccatataggaaaagctgtagatttaacaatcttctcattacacttagcaggaatttc
    atcaattttaggagctgttaattttatttcaacaattattaacatacgtttaaatttcct
    tacatttgatcaattaccactgtttgtttgatcagtaataattactgctattctcctctt
    actttctcttcctgtattagcaggagctatcactatattattaacagatcgaaatataaa
    tacttccttttttgatcctgctggaggaggggatccaattctataccagcacttattc


    En gras c'est les nom de genre, en souligné les espèces et en italique les séquences.

    Il y a plusieurs séquences d'espèces différentes mais d'un même genre et justement j'aimerais obtenir un fichier pour chaque genre contenant toutes les séquences des espèces appartenant à ce genre.
    0
  8. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    j'avais pris les mots GENRE et especes litteralement.essayer ça
    $ awk -F"[>|]" '/^>[A-Z]/ {nom=$2 ; sub("[a-z].*", "", nom) ; esp=$2 ; sub("^[A-Z]*", "", esp) ; x=" - " ; next} {print esp x $0 > nom ; x=esp="" }' fichier ; ls [A-Z]* | xargs -i sh -c 'cat f2 >> {}'
    $ ls
    CHIMARRA  HYDROPSYCHE  TRIAENODES 
    $ 
    0
  9. ONI
     
    Merci beaucoup, je vais tester ça ce WE, je viendrais dire si j'ai réussi \o/ ou non /o\.
    0
  10. ONI
     
    Re bonjour,
    Alors j'ai lancé la ligne de commande et ça a presque marché comme voulu sauf que j'ai eu le message d'erreur suivant et il me manque pas mal de genres ainsi que des espèces (+ séquences) dans les fichier de genre créés.

    macbook-de-admin-5:co1 User$ awk -F"[>|]" '/^>[A-Z]/ {nom=$2 ; sub("[a-z].*", "", nom) ; esp=$2 ; sub("^[A-Z]*", "", esp) ; x=" - " ; next} {print esp x $0 > nom ; x=esp="" }' co1.txt ; ls [A-Z]* | xargs -i sh -c 'cat Tref.fasta >> {}'
    awk: WORMALDIA makes too many open files
    input record number 830, file co1.txt
    source line number 1
    xargs: illegal option -- i
    usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]
    [-L number] [-n number [-x]] [-P maxprocs] [-s size]
    [utility [argument ...]]

    Mais la forme de sorti est bien celle attendu.
    0
  11. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    essayer ça :
    il n'y a plus de xargs, il y a un close qui devrait éviter le too many open files
    le fichier f2 contient la ligne à ajouter, le fichier f3 les données
    $ awk -F"[>|]" -v t="$(cat f2)" '/^>[A-Z]/ {p=0 ; if(n){print  t > n ; close(n)} n=e=$2 ; sub("[a-z]*$", "", n) ; sub("^[A-Z]*", "", e) ; e=e " - "} p++ {print e $0 > n ; e="" }  END{print t > n}' f3 
    $ 
    
    0
  12. ONI
     
    Alors j'ai l'impression que ça me fait tous les genres, mais j'ai qu'une seule séquence par genre et j'ai des fichiers du genre : BRACHYCENTRUSsp.07EVBAR-0021 en plus du simple fichier BRACHYCENTRUS.
    0
  13. ONI
     
    Et en fait la ligne que j'ai a rajouter à chaque fois c'est pas juste une ligne, je me suis planté, c'est un fichier contenant ça :

    >gb|AY396143.1|:1-1567 Lepidostoma flavum cytochrome oxidase subunit I (COI) and cytochrome oxidase subunit II (COII) genes, partial cds; mitochondrial genes for mitochondrial products
    actgcatctctgagagagctagctctcgaacagcttacag.....
    0
  14. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    le fichier f2 peut contenir plusieurs lignes à ajouter, pas de problèmes
    je me basais sur les majuscules pour le nom et des minuscules pour l'espèce.
    donc il peut avoir un nom et plusieurs espèces ?
    BRACHYCENTRUSxxxxxxx et BRACHYCENTRUSzzzzzzzzzz et dans le fichier BRACHYCENTRUS il doit y avoir xxxx et zzzz ?
    0
  15. ONI
     
    Ok.

    Oui c'est ça il y plusieurs espèces avec le même nom de genre, ça l'avait bien fait dans ton avant dernière ligne de commande (enfin pas pour toutes les espèces).
    0
  16. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    essayer ca:
    j'ai remis le xargs mais avec une autre option ca devrait passer, j'ai du enlever le close, puisque un fichier peut etre accédé plusieur fois. Sur Mac (si tu es sur Mac ? ) n'y a-t-il par un autre awk, tel que nawk ou gawk ?
    $ awk -F"[>|]" '/^>[A-Z]/ {p=0 ; n=e=$2 ; sub("[^A-Z].*$", "", n) ; sub("^[A-Z]*", "", e) ; e=e " - "} p++ {print e $0 > n ; e="" }' f3 ; ls [A-Z]* | xargs -I{} sh -c 'cat f2 >> {}' 
    
    0
  17. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    compter le nombre de fichiers à créer:
    $ grep -o '^>[A-Z]*' f3 | sort -u | wc -l
    compter le nombre de fichiers accédés plusieurs fois
    $ grep -o '^>[A-Z]*' f3 | sort | uniq -d | wc -l
    0
  18. ONI
     
    Donc oui je suis sur mac et j'ai pas trouvé de n ou gawk.

    Pour la ligne de commande ça m'a fait la même erreur que :
    awk -F"[>|]" '/^>[A-Z]/ {nom=$2 ; sub("[a-z].*", "", nom) ; esp=$2 ; sub("^[A-Z]*", "", esp) ; x=" - " ; next} {print esp x $0 > nom ; x=esp="" }' fichier ; ls [A-Z]* | xargs -i sh -c 'cat f2 >> {}'

    C'est à dire que tous les genres ne sont pas fait et qu'il manque des espèces pour les gens fait.
    0
  19. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    quelle même erreur : too many open files ?
    compte le nombe de fichiers à créer, voir post #16
    0
  20. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    on compte chaque genre pour ne fermer que les fichiers genres présents qu'une fois, ca devrait faire moins de fichiers ouverts.
    mettre ce code dans fichier.awk
    BEGIN{while("cat f3" | getline)
            {if($0 ~ /^>[A-Z]/){a=$0; sub(">", "", a);sub("[^A-Z].*$", "", a) ; x[a]++ }}}
    /^>[A-Z]/ {p=0 ; if(n && (x[n]<2))close(n) ; n=e=$2 ; sub("[^A-Z].*$", "", n) ; sub("^[A-Z]*", "", e) ; e=e " - "}
    p++ {print e $0 > n ; e="" }
    et exécuter
    awk -F"[>|]" -f fichier.awk f3 ; ls [A-Z]* | xargs -I{} sh -c 'cat f2 >> {}'
    0
  21. ONI
     
    Voilà pour les comptages :
    compter le nombre de fichiers à créer:
    $ grep -o '^>[A-Z]*' f3 | sort -u | wc -l --> 52
    compter le nombre de fichiers accédés plusieurs fois
    $ grep -o '^>[A-Z]*' f3 | sort | uniq -d | wc -l --> 41

    Et pour l'erreur c'est la même que la première avec le xargs et le fait qu'il manque des genres.

    Si tu veux je peux t'envoyer mes fichiers pour que tu vois concrètement à quoi ça ressemble.
    0
  • 1
  • 2
  • 3