cours OBI1 jour 3
Transcription
cours OBI1 jour 3
Jour 3: Interpréteur awk, expressions régulières (suite) : les expressions régulières et leur utilisation dans le traitement de l'information biologique (grep, egrep). Application au traitement des entr ées/sorties des logiciels. Cours OBI1 jour3 – Expressions régulières – sed/awk Les expressions régulières Elles servent à identifier une chaîne de caractères répondant à certains critères (ex : une chaîne contenant uniquement des majuscules). Elles sont utiles dans vi, more, less, sed, awk, grep,egrep… On décrit la chaîne position par position. Métacaractères = caractères spéciaux . tout sauf \n [ ] alternative [Tt]oto reconnaît Toto et toto [A-D]oto reconnaît Aoto, Boto, Coto, Doto [2-56]oto reconnaît 2oto, 3oto, 4oto, 5oto, 6oto [aA-] le – situé à la fin des crochets perd son caractère spécial (intervalle) et correspond au tiret. [^ ] tout sauf [^0-9]oto reconnaît oto précédé de n’importe quoi sauf un nombre [1-3^] le ^perd son caractères spécial donc reconnaît 1oto, 2oto, 3oto,^oto ^ si il n’est pas entre crochet, il symbolise début de ligne ^a reconnaît les lignes qui commencent par a $ fin de ligne $a reconnaît les lignes qui se terminent par a ^toto$ recoonaît les lignes qui ne contiennent que toto ^$ reconnaît les lignes vides ? caractère présent 0 ou une fois to?to reconnaît tto et toto * répétition d’un caractère de 0 à plusieurs fois to*to reconnaît tto, toto, tooto,… + répétition d’un caractère de 1 à plusieurs fois to+to reconnaît toto, tooto… ATTENTION, certains métacaractères n’existent pas dans certains programmes. C’est le cas du + qui n’existe pas dans sed et on remplacera l’expression ci dessus par too*to. {x,y} répétition d’un caractère de x à y fois to{1,3}to reconnaît toto, tooto, toooto to{2,}to signifie que le o en position 2 sera répété au moins deux fois to{40}to signifie que le o sera répété exactement 40 fois ATTENTION, les accolades ne sont pas des métacaractères dans egrep, on utilisera grep si on veut les utiliser. ( | ) alternative entre des sous-chaînes ta(ta|ble) reconnaît tata et table \ fait perdre son caractère spécial au métacaractère toto\. reconnaît toto suivi d’un point. sed / awk sed c'est un éditeur de lignes. Il traite donc l'entrée ligne par ligne comme le fait egrep. syntaxe générale: sed -e 'commande' c'est-à-dire sed -e '/pattern/action' pour que l'action demandée soit appliquée à chaque ligne contenant le pattern (regexp). Si on ne met pas de pattern, l'action sera éxécutée sur chaque ligne du fichier. On peut aussi restreindre l'action à certaines lignes à partir de leur numéro dans le fichier sed -e 'number(s) action'. On peut combiner le tout pour effectuer les actions sur les lignes ayant tels numéros et contenant tel pattern … On utilise souvent sed en ligne de commande pour sa fonction simple rechercher/remplacer (substitute) avec les expressions régulières. Syntaxe : sed -e '/pattern/s/regex/chaîne/' ou sed -e 's/regex/chaîne/' cat fichier | sed -e 's/^>/Titre : /' remplace le “>” qui débute une ligne par la chaîne “Titre : ” Si on veut éliminer les lignes qui commence par un # : cat fichier | sed -e '/^#/d' (delete) cat fichier | sed -e '12q' (q veut dire quitter) permet de quitter lorsque la ligne 12 est atteinte ce qui revient à head -12. cat fichier | sed -e '12d' va déléter la ligne 12 du fichier. sed -e '1,3 d' fichier va déléter les trois premières lignes. sed -e '3,$ d' fichier va déléter les lignes à partir de la troisième et jusqu'à la fin du fichier. Pour effectuer plusieurs commandes sed à la suite on peut écrire en lignes de commandes cat fichier | sed -e 'commande1' -e 'commande2' … OU cat fichier | sed -f sedscript si on a écrit les commande sed dans le fichier sedscript qui contient les commandes à appliquer en ligne: commande1 et commande2 Attention, certaines expressions régulières ne fonctionnent pas dans toutes les commandes unix. Par exemple, l'expression a\{3,5\}b veut dire un a répété de 3 à 5 fois suivi d'un b dans egrep et sed, mais ne marche pas dans grep. De la même façon, dans sed, le signe + (un symbole présent au moins une fois) n'existe pas et doit être remplacé par l'* en écrivant deux fois le symbole avant (le symbole une fois + le symbole de zéro à n fois) . Si on veut reconnaître un certain pattern afin de le réécrire entre parenthèse, on peut utiliser & qui permet de rappeler l'ensemble de la regexp reconnue dans l'action rechercher/remplacer. cat fichier | sed -e 's/^#/(&)/' va mettre entre parenthèses le # des débuts de ligne. Par défaut l'action n'est effectuée qu'une seule fois par ligne : cat fichier | sed -e 's/a/x/' remplace le premier a des lignes du fichier par un x (un seul remplacement par ligne). Le flag g (pour « global ») permet de remplacer tous les a des lignes du fichier par des x. cat fichier | sed 's/a/x/g'. Utilisation des sous-expressions régulières : cat fichier | sed -e 's/\([a-z]\)x/\1y/' remplace bx par by et mx par my. La sous-expression est entre parenthèses « backslashées » et est rappelée par \son_numéro car on peut mettre plusieurs sous-expressions dans une regexp. cat fichier | sed -e 's/\([a-z]\)\(x\)/\2\1/' remplace bx par xb et mx par xm. Exercice : un fichier « fich » avec sur chaque ligne nom prénom. On veut inverser et avoir en sortie chaque ligne avec prénom nom. cat fich | sed -e 's/\([A-Za-z-][A-Za-z-]*\) *\([A-Za-z-][A-Za-z-]*\)/\2 \1/' awk cat fichier | awk 'programme' OU awk -f scriptawk cat fichier | awk 'BEGIN {commande1} /regex1/ {commande2} /regex2/ {commande3} {commande4} END {commande5}' awk traite les fichiers, ou ce qu'on lui donne en entrée ligne par ligne comme sed, grep… les commandes sont entre accolades et séparées par des “;”. Le BEGIN est optionnel et contient les commandes qui seront exécutées une seule fois avant même le début du traitement des lignes. Le END est lui aussi optionnel et suivi des commandes qui seront exécutées une seule fois après le traitement de l'ensemble des lignes. Lorsqu'un bloc est précédé d'un pattern (ici les blocs commande2 et commande3), il n'est effectué que si la ligne traitée contient ce pattern. Le bloc commande4 ici serait effectué à chaque ligne traitée. cat fichier | awk '/^>/ {print “titre”, NF} Attention, dans sed les lignes non traitées étaient réécrites telles quelles sur la sortie. AWK n'écrit que le résultat de son traitement. Ici, le awk va à chaque fois qu'il rencontrera une ligne commençant par “>” écrire titre et le contenu de la variable NF à l'écran (si la ligne ne commence pas par « > » il n’écrira rien à l’écran). La variable NF est une variable awk qui est modifiée pour chaque ligne traitée et contient le nombre de champs (colonnes = number of fields) de la ligne. Ces champs sont séparés par défaut par un blanc mais on peut le changer avec l’option -F qui modifie la variable FS (Field Separator) de awk. La commande suivante indiquera à awk de prendre les « ; » comme séparateur (à la place des blancs) : awk –f ‘ ;’ fichier Attention NF est une variable dans awk et si je veux écrire son contenu j'écris print NF et non print $NF comme en c-shell. $NF a une autre signification dans awk c'est le contenu du dernier champ de la ligne. $1 = premier mot; $2=deuxième mot … $NF=dernier champ. $0 correspond à toute la ligne. NR correspond au numéro de la ligne traitée (number of the record). Jean :dupont:24 rue saint Honoré NF = 5 si FS = ' ' et NF = 3 si FS = ':' Si FS=' ', $NF est le mot 'Honoré', si FS= : ', $NF est le mot « 24 rue saint Honoré » . cat fichier | awk '/^>/ {print $0}' imprime juste les titres des séquences comme un grep. cat fichier | awk '{print $0}' imprime toutes les lignes comme un cat. On peut écrire avec awk de vrais petits programmes avec des boucles for et des tests if. On veut par exemple écrire pour chaque ligne d'un fichier les mots avec un mot par ligne. On va utiliser la fonction print qui va à la ligne automatiquement avec 'print $i' pour i allant de 1 à NF pour chaque ligne traitée. cat fichier | awk '{for(i=1; i<=NF;i++) {print $i}}' Le i =1 est effectué une fois au départ puis test i<=NF. Si le test i<=NF est vrai, le bloc d’instruction{print $i} est effectué, puis incrémentation de i de 1, puis test…etc jusqu’à ce que le test soit faux. (on sort alors de la boucle et on va à l’instruction suivante si il y en a une. On veut maintenant imprimer en ligne les mots commençant par 'a'. cat fichier | awk '{for(i=1; i<=NF;i++) {if ($i~/^a/) {print $i}else {…}}}'. Notion de dictionnaire : indexation par des chaînes de caractères et non des entiers dico[“anne”] = 14 dico[“louis”] = 17 dico[“vincent”] = 12 Parcourir un dictionnaire : for (i in dico) {print i, dico[i]} sort et uniq Si on veut faire un dictionnaire des mots contenus dans un fichier on pourra utiliser sort et uniq souvent utilsés pour les tris. cat fichier | awk '{for(i=1; i<=NF;i++) {pint $i}}' | sort | uniq Par défaut sort trie alphabétiquement les lignes. Pour le tri numérique, il faut utiliser l’option –n (comme numérique) : sort sur des lignes contenant des nombres 1 à 20 donnerait 1,10,11,…19,2,20 (qui est l’ordre alphabétique des nombres de 1 à 20). sort -n donnera les lignes 1,2,3,4,…10,11,…20 (ordre numérique). exercice : A partir d'un fichier de séquences en fasta on veut que les séquences soient écrites sur une seule ligne par exemple pour rechercher facilement des motifs dessus. cat fichier | awk 'BEGIN {s=' '} /^>/ {if (s !=“”) {print s; s= “”}; print $0} /^[A-Za-z]/ {s=s$0} END {print s}' Fonctions awk substr(s,5,10) sous-chaîne à partir du cinquième caractère de s sur une longueur de 10 gsub('A', 'V', $0) substitue dans $0 les A (regexp) par des V (chaîne). Si pas de troisième argument, la fonction est par défaut appliquée à toute la ligne. split(s,t,':') découpe la chaîne de caractères s en mots rangés dans le tableau t selon le séparateur ':'. Et bien sûr, ne pas oublier man awk… TP Petits exercices : Création d’un fichier fasta avec la séquence sur une seule ligne cat mygee.faa | awk ‘BEGIN{s= ""} /^>/ {if (s != "") {print s ;s= ""} ; print $0} /^[A-Z]/ {s=s $0} END print s}’ recherche du pattern des métallo protéases cat mygee.faa | awk ‘BEGIN{s= ""} /^>/ {if (s != "") {print s ;s= ""} ; print $0} /^[A-Z]/ {s=s $0} END print s}’ | egrep "HE..H" remplacement des zones de faibles complexité (type EDEDDEEEDDE) avec des ‘@@@’ cat mygee.faa | awk ‘BEGIN{s= ""} /^>/ {if (s != "") {gsub("[ED][ED][ED][ED]+", "@@@") ; print s ;s= ""} ; print $0} /^[A-Z]/ {s=s $0} END print s}’ | egrep "HE..H" Compter les features d'un fichier genbank #!/usr/bin/gawk -f BEGIN /^ { [^ ]/ && /^FEATURES/ { /^BASE COUNT/ { ft = 0; } (ft == 1) { Table[$1]++ ;} ft = 1; } ft = 0; } END { for ( i in Table) print i,Table[i]; } Analyse du sens des gènes sur des chromosomes : 1°) Récupérer 2 fichiers de chromosomes: - celui de mycoplasma pneumoniae M129 (Aller sur http://www.tigr.org/tigrscripts/CMR2/CMRGenomes.spl, une fois sur le génome, allez sur lien « Genbank ftp »), prendre le fichier U00089.ffn (gènes en nucléotides) et le fichier U00089.gbk (format genbank) -le chromosome 11 de levure. Aller sur ftp://genomeftp.stanford.edu/pub/yeast/data_download/sequence/NCBI_genome_source/ Fichier chr11.gbf 2°) Regarder les fichiers (différents formats : fasta pour M129, genbank pour levure). Comment les traiter ? (repérage des gènes ou CDS et de leurs bornes, comment les extraire ?) 3°) Traiter chacun des fichiers Progressivement : cat U00089.gbk | egrep "^ CDS" | more cat U00089.gbk | egrep "^ CDS" | awk '{print $2}' | more cat U00089.gbk | egrep "^ CDS" | awk '{if ($2~"complement") {print NR, $2}}’ | more cat U00089.gbk | egrep "^ CDS" | awk '{if ($2~"complement") {print NR, "1"} else { print NR, "2"}}’ | more ressortir dans un fichier, et regarder avec gnuplot. faire la même chose avec chromosome de levure (pour ceux qui ont fini avant, tracer avec les vraies coordonnées des gènes en bases, cad le milieu du gène) utilisation de split Progressivement : cat U00089.gbk | egrep "^ CDS" | awk '{if ($2~"complement") {s=1} else {s=2}; gsub("[a-z()]","",$2);print $2,s}' | more cat U00089.gbk | egrep "^ CDS" | awk '{if ($2~"complement") {s=1} else {s=2}; gsub("[a-z()]","",$2);split($2,t,".");print $2,t[1],t[3],s}' | more cat U00089.gbk | egrep "^ CDS" | awk '{if ($2~"complement") {s=1} else {s=2}; gsub("[a-z()]","",$2);split($2,t,".");print $2,t[1]+(t[3]-t[1])/2.0,s}' | more ressortir dans un fichier, tracer avec gnuplot 4°) calculer la probabilité d’avoir un sens suivi d’un antisens Application ancienne : calculette polonaise inverse (script awk) #!/usr/bin/awk -f #calculette polonaise inverse BEGIN { sommet = 0 } ($1 ~ /[0-9]+/) {#je rencontre un nombre pile[sommet] = $1; sommet++; } ($1 == "+") {#je rencontre un opérateur + pile[sommet-2] = pile[sommet-2] + pile[sommet-1]; sommet--; } ($1 == "-") {#je rencontre un opérateur pile[sommet-2] = pile[sommet-2] - pile[sommet-1]; sommet--; } ($1 == "*") {#je rencontre un opérateur * pile[sommet-2] = pile[sommet-2] * pile[sommet-1]; sommet--; } ($1 == "/") {#je rencontre un opérateur / pile[sommet-2] = pile[sommet-2] / pile[sommet-1]; sommet--; } ($1 == "log") {#je rencontre un log pile[sommet-1] = log(pile[sommet-1]); } END { print "\nresultat = " pile[sommet-1] "\n"; }