Problème argument pour grep et boucle for

Résolu
ONI -  
dubcek Messages postés 19021 Statut Contributeur -
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 ;).
A voir également:

41 réponses

ONI
 
Je viens de lancer tes dernières lignes de codes (en changeant les f2 et f3 dans les 2 lignes) et ça me créer des fichiers quasiment bons mais il manque encore des genres plus l'affichage d'une erreur :

umr5023bel05port:co1 mguenier$ awk -F"[>|]" -f fichier.awk co1.txt ; ls [A-Z]* | xargs -I{} sh -c 'cat bla >> {}'
awk: CERACLEA makes too many open files
input record number 806, file co1.txt
source line number 4



Cependant là j'ai plusieurs espèces par genre comme attendu.
0
dubcek Messages postés 19021 Statut Contributeur 5 640
 
il faudrait compter les genres pour voir à combien arrive le too many ...
https://forums.commentcamarche.net/forum/affich-24824669-probleme-argument-pour-grep-et-boucle-for?full#16
0
ONI
 
J'ai fait un post (plus tôt) où je te donnais le résultats des comptages ^^.
0
dubcek Messages postés 19021 Statut Contributeur 5 640
 
désolé, je l'avais raté
Si tu veux je peux t'envoyer mes fichiers pour que tu vois concrètement à quoi ça ressemble.
volontier parce je vois mal le too many open files avec ces petits nombres.
chez moi, la limite est 1022
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ONI
 
Je te l'envoi comment (mail, skype etc...)?
0
dubcek Messages postés 19021 Statut Contributeur 5 640
 
regarder là : https://www.commentcamarche.net/faq/2966-envoyer-des-fichiers-lourds-pieces-jointes-par-e-mail
et tu peux mettre le lien ici ou l'envoyer en message privé
0
zipe31 Messages postés 38797 Date d'inscription   Statut Contributeur Dernière intervention   6 434
 
Salut,

ou l'envoyer en message privé
Il faut être inscrit pour ça ;-\
0
ONI
 
Pas envi de m'inscrire mais merci ;).
0
zipe31 Messages postés 38797 Date d'inscription   Statut Contributeur Dernière intervention   6 434
 
Ce n'était point dit dans ce sens là, mais juste pour expliquer que le message privé n'allait pas être possible ;-)
0
ONI
 
Ahh ^^ ok.
0
ONI
 
http://dl.free.fr/oNxEURaNU

Alors ceci c'est mon fichier principal avec toutes les informations : noms de genre, noms d'espèce et séquences.

http://dl.free.fr/vXFfU62QJ

Et ceci c'est le fichier qui est à rajouté à la fin de chaque fichier de genre.
0
dubcek Messages postés 19021 Statut Contributeur 5 640
 
essayer ce code:
/^>[A-Z]/       {p=0 ;  n=e=$2 ; sub("[^A-Z].*$", "", n) ; sub("^[A-Z]*", "", e) ; e=e " - "}  
p++             {print e $0 >> n ; close(n) ; e="" }
avec
$ awk -F"[>|]" -f fichier.awk co1.txt ; for f in [A-Z]*[A-Z] ; do cat Tref.fasta >> $f;done
- une boucle remplace le xargs
- le awk fait un close à chaque print donc c'est plus long
- il ajoute toujours aux fichiers, donc il faut les supprimer avant de réexécuter

edit: j'ai enlevé la ligne BEGIN {..} elle est inutile
0
ONI
 
le fichier.awk c'est le même que précédemment?
0
ONI
 
La première ligne ne marche pas et m'affiche cette erreur :

umr5023bel05port:co1 mguenier$ /^>[A-Z]/{p=0 ; n=e=$2 ; sub("[^A-Z].*$", "", n) ; sub("^[A-Z]*", "", e) ; e=e " - "} p++ {print e $0 >> n ; close(n) ; e="" }
-bash: syntax error near unexpected token '"[^A-Z].*$",'
0
zipe31 Messages postés 38797 Date d'inscription   Statut Contributeur Dernière intervention   6 434
 
Cette ligne c'est le contenu du fichier "fichier.awk" ;-((
0
ONI
 
ah ^^, si on le dit pas moi.
0
dubcek Messages postés 19021 Statut Contributeur 5 640
 
ouep, pardon
0
ONI
 
\o/ je pense que c'est bon ^^. J'ai 52 fichier de Genre et dedans j'ai toutes les espèces (vérifié pour les 2 premiers genres).

Merci infiniment tu m'aides gavé ^^, j'espère juste que mon soft va pouvoir lire ça sans problème.

Il faut que je fasse la même manip pour un autre groupe de bestioles, le type de fichier change pas, mais le contenu si (nom de genre etc...) je suppose que ça posera pas de problème vu que la recherche se fait sur n'importe quelle majuscule?

Juste par curiosité et parce que j'aime pas trop faire des trucs que je ne comprend pas tu pourrais m'expliquer la signification et le rôle des différents arguments utilisés (si ça te déranges pas ^^).

Je te tiens au courant pour le fait de savoir si ça marche avec mon soft ou pas.

Encore merci.
0
ONI
 
Damned, mon soft les aime pas, mais je pense savoir pourquoi :

Le fichier est du genre ;
Nom de l'espèces - acgatctatcatcagagagctatagctcg......

Et je pense que le soft comprendrait :
Nom de l'espèces
acgatctatcatcagagagctatagctcg......

En gros, le nom et la séquence pas sur la même ligne.
0
dubcek Messages postés 19021 Statut Contributeur 5 640
 
changer e=e " - " par e=e "\n"
0
ONI
 
Ok, nikel, mais ça n'a pas réglé le problème. Pour que le soft prenne c'est lignes comme des séquences il faut que le fichier ressemble à ça :

>Nom de l'espèces
acgatctatcatcagagagctatagctcg......

Donc il faut juste rajouté un ">" avant chaque nom d'espèce. Je ne vois pas où le placer précisément dans les arguments de fichier.awk.
0
dubcek Messages postés 19021 Statut Contributeur 5 640
 
changer e=e "\n" par e=">" e "\n"
on aura donc >espèce[saut de ligne]
c'est de la concaténation de strings
0
ONI
 
Ok parfait, le soft les lis. Seul bémol c'est que il y a des séquences qui s'affichent pas dans mon soft, mais c'est pas une question de prog je pense.

Je tiens vraiment à te remercier, j'aurais jamais pu faire ça seul ^^.
0
dubcek Messages postés 19021 Statut Contributeur 5 640
 
v'la la doc. n'hésite pas à demander.
awk -F"[>|]"       # on definit > et | comme séparateurs

/^>[A-Z]/  # on ne traite que les lignes qui commencent par >[majuscule]
{p=0               # p est un compteur qui permet de sauter la ligne contenant print 1 seule fois
n=e=$2             # n et e valent $2, donc par ex. TRIAENODEStardus, le texte entre > et |
sub("[^A-Z].*$", "", n)    # on supprime tout ce qui n'est pas majuscule jusqu'à la fin, on a le genre
sub("^[A-Z]*", "", e)      # on supprime les majuscules du début, on a l'espèce
e=">" e "\n" }             # on ajoute un séparateur à l'espèce

p++        # si p n'est pas nul, donc on ignore les lignes >XXXX, on lit toutes les autres lignes tttatcaattttttctc....
{print e $0 >> n ; close(n)        # on ajoute l'espèce, puis la ligne ($0) et on ferme le flux, qui sera re-ouvert au prochain print
e="" }             # on efface l'espèce, de sorte qu'elle ne s'affiche qu'une seule fois pour un genre

for f in [A-Z]* ; do cat tref.fasta >> $f;done     # on ajoute le fichier tref.fasta à tout les fichiers qui commencent par une majuscule.

0
ONI
 
Hug,

Je reviens car j'ai un problème très con mais je l'avait pas vu venir.

Je replante le décor :
Je part d'un fichier qui ressemble à ça :

>TRIAENODEStardus|UNKNOWN_000000_CANADA:ONTARIO,WELLINGTON,ELORA,NEARncbi_JF434447|co1
ttgatctggattactaggaacatctttaagagtaataattcgaactgaattaggttcagt
aggatcattaattaaaaatgatcaaatttataatgtaatagttactgctcatgcttttat

>HYDROPSYCHEplacoda|UNKNOWN_000000_CANADA:ONTARIO,WELLINGTON,ELORA,NEARncbi_JF434387|co1
aacactttacttcatatttggaatttgatccggtcttattggatcttctataagatttat

Pour arriver à des fichiers comme ça :

fichier 1
>tardus
ttgatctggattactaggaacatctttaagagtaataattcgaactgaattaggttcagt
aggatcattaattaaaaatgatcaaatttataatgtaatagttactgctcatgcttttat

fichier 2
>placoda
aacactttacttcatatttggaatttgatccggtcttattggatcttctataagatttat

Le problème c'est que je me retrouve avec des fichiers du genre :

>tardus
ttgatctggattactaggaacatctttaagagtaataattcgaactgaattaggttcagt
aggatcattaattaaaaatgatcgc
>tardus
tcaggatcattaattaaaaatgatcaaatttataatgtaatagttactgctcatgcttttat
>tardus
ttctttaagagtaataattcgaactgaattaggttcagtaggatcattaattaaaaatga
tcaaatttataatgtaatagttactgctca

Parce qu'en fait j'ai différentes séquences d'une même espèce, mais à la fin de mes analyses j'ai besoin de les identifier une à une.
Donc j'ai 2 options je pense :

- soit je garde le nom complet devant chaque séquences et avoir un fichier du genre :

>TRIAENODEStardus|UNKNOWN_000000_CANADA:ONTARIO,WELLINGTON,ELORA,NEARncbi_JF434447|co1
ttgatctggattactaggaacatctttaagagtaataattcgaactgaattaggttcagt
aggatcattaattaaaaatgatcaaatttataatgtaatagttactgctcatgcttttat
>TRIAENODEStardus|UNKNOWN_0003215_USA:TEXAS,WELLINGTON,ELORA,NEARncbi_546857874|co1
ttgatctggattactaggaacatctttaagagtaataattcgaactgaattaggttcagt
aggatcattaattaaaaatgatcaaatttataatgtaatagttactgctcatgcttttat

- soit j'arrive à rajouté un caractère unique qui me permette de discriminer les séquences d'une même espèce :

>tardus1
ttgatctggattactaggaacatctttaagagtaataattcgaactgaattaggttcagt
aggatcattaattaaaaatgatcgcttttat
>tardus2
tcaggatcattaattaaaaatgatcaaatttataatgtaatagttactgctcatgcttttat
>tardus3
ttgatctggattactaggaacatctttaagagtaataattcgaactgaattaggttcagt
aggatcattaattaaaaatgatcaaatttataatgtaatagttactgctca
0
dubcek Messages postés 19021 Statut Contributeur 5 640
 
essayer ça
$ grep tardus  TRIAENODES 
tardus1 - ttgatctggattactaggaacatctttaagagtaataattcgaactgaattaggttcagt 
tardus2 - aacactatattttatttttggtgcttgatctggattactaggaacatctctaagagtaat 
tardus3 - aacactatattttatttttggtgcttgatctggattactaggaacatctctaagagtaat 
tardus4 - aacactatattttatttttggtgcttgatctggattactaggaacatctttaagagtaat 
... 
$ cat f1.awk 
/^>[A-Z]/ {p=0 ;  if(n && (x[n]<2))close(n) ; n=e=$2 ; sub("[^A-Z].*$", "", n) ; sub("^[A-Z]*", "", e) ; e=e sprintf("%d", ++x[e]) " - " } 
p++  {print e $0 >> n ; close(n) ; e="" } 
$ 
0
dubcek Messages postés 19021 Statut Contributeur 5 640
 
deuxième choix
$ grep tardus  TRIAENODES 
>TRIAENODEStardus|UNKNOWN_000000_CANADA:ONTARIO,WELLINGTON,ELORA,NEARncbi_JF434447|co1 
>TRIAENODEStardus|UNKNOWN_000000_USA:WASHINGTON,WHATCOMCO.,W.FERNDALE,L.ncbi_HM103311|co1 
>TRIAENODEStardus|UNKNOWN_000000_USA:MINNESOTA,OLMSTEAD,NORTHBRANCH,ROOTncbi_HM103309|co1 
>TRIAENODEStardus|UNKNOWN_000000_CANADA:ONTARIO,WELLINGTON,ELORA,NEARncbi_HM103312|co1 
.... 
$  cat f1.awk 
/^>[A-Z]/ {p=0 ; n=$2 ; sub("[^A-Z].*$", "", n) ; e=$0 "\n"} 
p++  {print e "\n" $0 >> n ; close(n) ; e="" } 
$  
0