Astuce :
Chercher des motifs dans un fichier

Langage : shell
Commandes présentées : grep, split (succintement)
Niveau : débutant

Présentation de la commande grep

La commande grep est disponible nativement sur la plupart des systèmes d'exploitation GNU/Linux. La plupart des utilisateurs utilisent cette commande pour rechercher un mot ou un groupe de mots, que nous appellerons motif (pattern en anglais), dans un fichier texte. Cependant cette commande ne se limite pas à du simple cas par cas.
Grep recherche le motif en parcourant tout le fichier texte du début jusqu'à la fin. Ainsi, autant pour un fichier de quelques lignes, le résultat sera quasi immédiat, autant pour un fichier de plusieurs milliers de lignes le résultat peut être plus ou moins long.
Dans ce billet je vous présenterai les différentes façons dont je me sers régulièrement de grep, que ce soit de la simple recherche d'un mot clé à la recherche, plus ou moins complexe, de plusieurs motifs.

Exemple d'une commande grep sans chercher le motif exact et avec une colorisation. Auteur : Nolwenn. Image libre de droit.


Pour les exemples qui suivront, je me base sur la liste des informations sur les gènes fournies par Entrez Gene du NCBI. Si vous êtes sous GNU/Linux et que vous souhaitez reproduire les exemples présentés, vous pouvez saisir les commandes suivantes dans un terminal :

Méthode basique

La commande grep vous apporte un grand soutien dans la recherche de motif(s), vous l'utilisez déjà certainement de façon très basique comme dans cet exemple :

Premier constat : si le motif est compris dans un motif plus grand alors que vous ne souhaitez récupérer que les lignes qui correspondent exactement à ce motif, alors vous récupérerez toutes les lignes comprenant ce motif, y compris celles ne vous intéressant pas. Le bruit alors généré peut s'avérer problématique en fonction du nombre d’occurrences retournées !
Dans l'exemple présenté ci-dessus, vous pouvez constater que grep retourne le gène HLA-A et le gène HLA-AS1.

Rechercher un motif exact

Pour trouver le motif exact, vous pouvez jouer avec les options et plus particulièrement l'option -w (ou - -word-regexp). Exemple :

Rechercher plusieurs motifs

Pour chercher plusieurs motifs, trois solutions s'offrent à vous :

  • faire une boucle sur la liste des motifs et faire des grep successifs ;
  • jouer avec les expressions régulières, chose que je vous recommande pour quelques motifs ;
  • passer en argument un fichier de motif, qui est plus recommandé si vous avec beaucoup de motifs à chercher.

Méthode de la boucle

Cette méthode est assez basique, je m'en suis servie dans mes tout premiers scripts shell, mais elle présente un gros inconvénient : le temps de calcul !
Bien que grep soit une commande rapide pour un motif, plus vous ferez de grep successifs et plus cela mettra de temps. Ainsi, si il ne faut qu'un dixième de seconde pour afficher le résultat pour un motif, faites le calcul pour la recherche de 100 motifs. Notez toutefois que, plus vous aurez de motifs à rechercher, plus il faudra du temps avant d'afficher les résultats.
Pour les plus débutants d'entre vous je vous présente une syntaxe à reproduire pour cette méthode, comme ça vous pourrez vous faire votre propre idée du temps de calcul en comparant avec les deux autres méthodes.

Méthode des expressions régulières

Pour chercher plusieurs motifs à l'aide des expressions régulières, vous allez devoir ajouter l'option -E (ou - -extended-regexp). Exemple :

Explication(s) de la ligne de commande : le caractère | est un caractère spécial utilisé dans les expressions régulières. Ce caractère indique à la commande grep qu'il doit trouver au moins un des deux motifs. Si on devait le formuler à un être humain, nous pourrions le traduire par : "dans le fichier Homo_sapiens.tsv, cherche moi toutes les lignes qui ont exactement le terme HLA-A ou le terme BCR1 et indique-les moi".

Méthode du fichier de motifs

Pour passer un fichier de motifs à la commande grep, vous devez passer par l'option -f (ou - -file=FILE).
Le fichier de motifs doit contenir un motif par ligne, ici, un extrait des gènes intervenant dans la glycolyse/glycogénogenèse chez l'homme (source KEGG) :

Une fois votre fichier de motifs créé, vous pouvez le fournir à la commande grep qui gérera alors l'ordre dans lequel les motifs seront recherchés et trouvés :

Notez toutefois que plus votre fichier de motifs contient des motifs, plus la commande grep mettra du temps avant de vous retourner le résultat. Pour cela je vous conseille de vous orienter du côté de la commande split afin de découper le fichier de motifs en plusieurs fichiers comme dans l'exemple suivant :

Cette méthode, dont j'ai trouvé la source sur ce blog en anglais, présente un bien meilleur avantage que celui de faire une boucle sur la liste des motifs avant de faire des grep successifs. Avec un fichier de motifs votre recherche sera plus rapide que si vous deviez faire 30 grep les uns à la suite des autres, et votre machine n'en sera que plus heureuse !
Il est vrai que sur l'exemple que je vous ai fourni ce n'est pas très parlant. Sur 65 gènes, grep -f ne met pas plus de temps qu'avec plusieurs fichiers. Cependant j'ai pu constater une importante différence, en terme de temps, sur une liste de 9 312 motifs, et ça, c'est sans contexte un must to know pour des motifs très nombreux.

Savoir sur quelle ligne apparait le motif

L'un des avantages que grep nous apporte, c'est la possibilité de connaître la ligne du fichier sur laquelle le motif a été trouvé. Pour cela vous devrez utiliser l'option -n comme dans l'exemple ci-dessous :

Sur mon système, une simple Crunchbang installée sous VirtualBox, voici le résultat que j'obtiens :

Le gène BCR1 a été trouvé sur la ligne 506. Et pour les amoureux des couleurs qui sont parmi vous, essayez l'option - -color si votre motif n'apparaît pas explicitement 😉 !

Afficher 2 lignes avant et 2 lignes après le motif trouvé

Grep est également capable de vous permettre d'afficher un nombre de lignes avant ou après le motif une fois celui-ci trouvé, en voici un exemple :

Le mot de la fin

La commande grep, bien qu'étant une commande très informatique et non destinée au domaine de la bioinformatique, est un outil majeur dont nous nous servons quotidiennement. Elle s'avère être un outil puissant pour peu que l'on sache l'utiliser. De plus, si vous avez des notions sur les pipelines, vous pouvez constater qu'elle peut être utilisée à d'autres fins que la simple recherche de motifs, en combinaison avec d'autres commandes et/ou d'autres programmes.


Merci à Guillaume Collet et Yoann M. pour leur relecture, et nos discussions enrichissantes sur cette commande.

  • À propos de
  • Issue d'une licence de biologie cellulaire et physiopathologie et d'un master de bioinformatique, je m'intéresse tout particulièrement au monde de la recherche et au domaine de la santé. J'ai travaillé dans l'unité 946 de l'INSERM, dirigée par Florence Demenais, où mon travail principal a été l'étude et la recherche de bases de données et d'outils d'intérêt majeur pour l'axe de recherche dans lequel j'étais impliquée. J'ai aussi travaillé à l'Institut Pasteur où j'ai été recrutée en tant qu'ingénieure bioinformaticienne dans le cadre du LabEx Milieu Intérieur et où ma mission principale a été de mettre en place une base de données pour la gestion de nos échantillons biologiques. Mes centres d'intérêt en bioinformatique sont : la mise en application de méthodes dans les domaines de la génomique, de la protéomique et les interactions gène-gène protéine-protéine pouvant nous apporter des informations sur leurs influences dans les maladies. Je travaille actuellement au service informatique de l'IBENS où j'ai été recrutée en qualité de développeuse d'applications !

3 commentaires sur “Chercher des motifs dans un fichier

  1. Bon résumé de la commande.
    La méthode de la boucle pour chercher plusieurs motifs est à proscrire. Amis débutants, j'espère que vous l'avez compris.

    Quand au split, c'est très astucieux, j'ajouterai juste un '&' en fin de ligne pour bénéficier de tous les CPU.

  2. Article interessant!

    Merci 😀

  3. Merci pour votre article !

    Pour compléter, j'ajouterais que vous pouvez aussi préciser l'option -F à grep si comme dans l'exemple vous avez une liste de chaînes de caractères et non des expressions régulières. Cela devrait bien booster votre grep. Par ailleurs, si vous avec accès à des ressources de calculs avec plusieurs coeurs, regardez aussi du coté de la commande parallel, il y des exemples de parallelisation très intéressant dans son manuel 😉

Laisser un commentaire