Rechercher un motif dans des fichiers et exclure un dossier avec find et grep

J’ai récemment eu besoin de dépanner un WordPress assez conséquent et j’ai eu besoin d’aller fouiller un peu dans les fichiers. C’était un site qui avait plusieurs années, avec beaucoup d’extensions qui généraient beaucoup de bruit et il avait des milliers de fichiers. Mon besoin était simple : rechercher un motif pour trouver le bon fichier à modifier sur le serveur web. Grep est un outil formidable pour rechercher du texte dans les fichiers via le terminal de Linux. Sauf que sur ce cas précis, j’avais un problème à cause d’une extension en particulier.

Le besoin s’est alors légèrement transformé et c’est l’objet de cet article, je voulais maintenant chercher un motif de texte dans les fichiers tout en excluant un sous-dossier, car sinon j’ai trop de résultats en retour. Pour faire cela, je vais utiliser grep, mais aussi l’outil find que j’avais utilisé dans ce tutoriel pour classer les résultats d’une recherche par la taille des fichiers. Les commandes dans le shell de Linux peuvent paraître intimidantes, mais c’est vraiment extrêmement puissant et il serait dommage de ne pas apprendre à les utiliser.

Faire une recherche dans les fichiers d’un dossier mais exclure un sous-dossier

Je ne vais pas tourner plus longtemps autour du pot et vous donner cette commande sur le shell bash qui m’a été très utile. Pour rechercher dans les fichiers d’un dossier et ses sous-dossiers tout en excluant un des sous-dossier en utilisant find et grep il faut alors faire la chose suivante :

find /home/zonetuto/projet.prod -type f -not -path "/home/zonetuto/projet.prod/wp-content/cache/wp-rocket/*" -exec grep -l "LeMotifTexte" {} +

Si vous voulez l’explication complète de cette commande find avec grep, voici ce qu’il se passe :

  1. find: C’est le nom de la commande. find est utilisé sous Unix/Linux pour rechercher des fichiers et des répertoires dans une hiérarchie de fichiers.
  2. /home/zonetuto/projet.prod: C’est le répertoire de départ pour la recherche. La commande cherchera dans ce répertoire et tous ses sous-répertoires.
  3. -type f: Cette option indique à find de rechercher uniquement des fichiers (f signifie « file » en anglais). Elle exclut donc les répertoires, les liens symboliques, etc.
  4. -not -path « /home/zonetuto/projet.prod/wp-content/cache/wp-rocket/* »: Cette partie exclut un chemin spécifique de la recherche. Ici, tous les fichiers situés dans le répertoire wp-rocket et ses sous-répertoires seront ignorés. Cela est utile pour éviter de rechercher dans les fichiers de cache qui pourraient fausser les résultats.
  5. -exec grep -l « LeMotifTexte » {} +: Cette partie spécifie une commande à exécuter pour chaque fichier trouvé qui correspond aux critères précédents.
    • -exec: Indique à find d’exécuter une commande sur chaque fichier trouvé.
    • grep -l « LeMotifTexte »: grep recherche le motif spécifié (« LeMotifTexte » dans ce cas) dans les fichiers. L’option -l indique à grep de n’afficher que les noms des fichiers où le motif est trouvé, sans afficher les lignes correspondantes.
    • {} +: Remplace chaque fichier trouvé par find. Le + à la fin indique que la commande grep est exécutée une fois pour plusieurs fichiers trouvés, ce qui est plus efficace que de l’exécuter séparément pour chaque fichier.

Ce genre de commande et les outils qu’elle utilise sont extrêmement bien optimisés. Je n’ai jamais eu de soucis même avec des énormes volumes de données et un très grand nombre de fichiers. Il faut juste être patient dans le pire des cas, mais ça ne plantera pas. Vous pouvez bien sur le faire vous-même avec un script, mais si une simple commande permet de faire la même chose pourquoi ne pas en profiter ? En parlant de commande, si vous voulez facilement retrouver une commande dans votre historique avec grep, allez y faire un tour, c’est vraiment très pratique !

Si vous vous attendez à avoir beaucoup de résultats ou que vous voulez simplement stocker cette information, rien de plus simple. Pour rediriger le résultat de votre commande find dans un fichier texte, vous devez utiliser l’opérateur de redirection > suivi du chemin et du nom du fichier où vous souhaitez enregistrer les résultats. Voici comment vous pouvez le faire avec votre commande :

find /home/zonetuto/projet.prod -type f -not -path "/home/zonetuto/projet.prod/wp-content/cache/wp-rocket/*" -exec grep -l "LeMotifTexte" {} + > resultat_recherche.txt

Exclure plusieurs sous-dossiers de la recherche

Pour clore cet article, voici une solution qui a ses limites dans ce contexte mais qui peut dépanner pour des recherches rapides, comment exclure plusieurs sous dossier lors de votre recherche ?

Pour exclure plusieurs sous-dossiers avec votre commande find, vous pouvez répéter l’option -not -path pour chaque sous-dossier que vous souhaitez exclure. Voici comment vous pouvez ajuster votre commande pour exclure plusieurs sous-dossiers :

find /home/zonetuto/projet.prod -type f \
-not -path "/home/zonetuto/projet.prod/wp-content/cache/wp-rocket/*" \
-not -path "/home/zonetuto/projet.prod/chemin/vers/autre/dossier/exclu/*" \
-not -path "/home/zonetuto/projet.prod/chemin/vers/un/autre/dossier/exclu/*" \
-exec grep -l "LeMotifTexte" {} +

C’est utile pour dépanner, mais ce n’est pas la solution la plus « propre » et si vous avez un grand nombre de chemin, votre commande va vite devenir interminable. Il est possible de faire quelque chose un peu mieux, mais on arrive à la fin de cet article. Ultime bonus, si vous avez beaucoup de dossier à exclure de la recherche, dans ce cas utilisez plutôt un fichier texte qui va rationaliser un peu la ligne de commande :

find /home/zonetuto/projet.prod -type f | grep -vf exclusions.txt | xargs grep -l "LeMotifTexte" > resultat_recherche.txt

Bonnes recherches et résolution de bug !

1 réflexion au sujet de « Rechercher un motif dans des fichiers et exclure un dossier avec find et grep »

  1. Bonjour,
    grep seul devrait suffire :
    si la commande est exécutée à partir de /home/zonetuto/projet.prod/wp-content/
    grep -R –exclude-dir= »wp-rocket » -l « LeMotifTexte » (chemin relatif sans le »./ »)
    devrait donner le même résultat que le premier « find » de l’article.
    L’option –exclude-dir= peut être donnée plusieurs fois, c’est une « globbing » pattern (wp-* par exemple) et ne peut donc pas contenir de caractère « / ».
    Il existe d’autres options de grep qui permettent de restreindre le champ de recherche, par exemple –exclude= »*.txt » ou –exclude-from=nom_de_fichier

    Répondre

Laisser un commentaire