Linux pour les devs - 07 - grep et find en profondeur

Maitriser grep et find pour chercher du texte et des fichiers sous Linux, avec ripgrep comme alternative moderne.

  1. 01 Linux pour les devs - 00 - Pourquoi Linux meme si tu codes sur Mac ou Windows
  2. 02 Linux pour les devs - 01 - Le terminal, bash et zsh
  3. 03 Linux pour les devs - 02 - Fichiers et répertoires
  4. 04 Linux pour les devs - 03 - Permissions et droits d'acces
  5. 05 Linux pour les devs - 04 - Utilisateurs, groupes et sudo
  6. 06 Linux pour les devs - 05 - nano, vim, sed et awk
  7. 07 Linux pour les devs - 06 - Pipes et redirections
  8. 08 Linux pour les devs - 07 - grep et find en profondeur
  9. 09 Linux pour les devs - 08 - Les processus : comprendre ce qui tourne sur ta machine
  10. 10 Linux pour les devs - 09 - systemd : gerer tes services comme un pro
  11. 11 Linux pour les devs - 10 - Le réseau : comprendre ce qui passe par le fil
  12. 12 Linux pour les devs - 11 - Le firewall : contrôler qui entre et qui sort
  13. 13 Linux pour les devs - 12 - SSH : l'acces distant sécurisé
  14. 14 Linux pour les devs - 13 - Les variables d'environnement : configurer sans hardcoder
  15. 15 Linux pour les devs - 14 - Scripts bash : automatiser pour ne plus se répéter
  16. 16 Linux pour les devs - 15 - cron : les taches planifiees
  17. 17 Linux pour les devs - 16 - Les logs : lire, filtrer, comprendre
  18. 18 Linux pour les devs - 17 - Stockage et disques
  19. 19 Linux pour les devs - 18 - Les gestionnaires de paquets
  20. 20 Linux pour les devs - 19 - Les conteneurs sans Docker
  21. 21 Linux pour les devs - 20 - Securiser un serveur Linux
  22. 22 Linux pour les devs - 21 - Performance et diagnostic
  23. 23 Linux pour les devs - 22 - tmux : le multiplexeur de terminal
  24. 24 Linux pour les devs - 23 - Glossaire Linux

07 - grep et find en profondeur

Ce que tu vas apprendre

  • grep avec toutes ses options utiles (-r, -i, -n, -l, -v, -E, -c)
  • find avec -name, -type, -mtime, -size, -exec, -delete
  • Combiner grep et find pour des recherches chirurgicales
  • ripgrep (rg) comme alternative moderne et rapide
  • locate, which, whereis et type

Prerequisites

Connaitre les pipes et les redirections. Voir l'article sur les pipes.


La recherche, c'est 50% du boulot

Serieusement. Que tu debugges un bug, que tu cherches ou une variable est définie, ou que tu traques un fichier de config perdu, tu passes une bonne partie de ta journee a chercher des choses. Maitriser grep et find, c'est diviser ce temps par dix.

grep : chercher du texte

grep cherche un motif dans des fichiers ou dans un flux (via pipe). C'est probablement la commande que j'utilise le plus apres ls et cd.

Les options de base

bash# Chercher un mot dans un fichier
grep "error" application.log

# Les options indispensables
grep -i "error" app.log          # Insensible a la casse (Error, ERROR, error)
grep -n "error" app.log          # Affiche les numeros de ligne
grep -c "error" app.log          # Compte le nombre d'occurrences
grep -l "TODO" src/*.ts          # Affiche seulement les noms de fichiers
grep -v "debug" app.log          # Inverse : lignes qui NE contiennent PAS "debug"

# Combiner
grep -in "error" app.log         # Insensible a la casse + numeros de ligne

Recherche recursive

bash# Chercher dans tous les fichiers d'un repertoire
grep -r "TODO" src/

# Avec numeros de ligne (le plus courant)
grep -rn "TODO" src/

# Exclure des dossiers
grep -rn "import" src/ --exclude-dir=node_modules --exclude-dir=.git

# Exclure des types de fichiers
grep -rn "console.log" src/ --include="*.ts" --include="*.tsx"

# Seulement les noms de fichiers (utile quand il y a beaucoup de resultats)
grep -rl "deprecated" src/

Contexte autour des résultats

Quand tu cherches une erreur dans un log, tu veux souvent voir ce qu'il y a autour :

bash# 3 lignes apres chaque match
grep -A 3 "Exception" app.log

# 2 lignes avant chaque match
grep -B 2 "Exception" app.log

# 2 lignes avant ET apres (contexte)
grep -C 2 "Exception" app.log

# Exemple concret : voir le contexte d'une erreur dans les logs
$ grep -B 2 -A 5 "NullPointerException" server.log
2026-03-29 10:30:01 INFO Processing request /api/users/42
2026-03-29 10:30:01 DEBUG Fetching user from database
2026-03-29 10:30:01 ERROR NullPointerException
    at UserService.getUser(UserService.java:42)
    at UserController.handleRequest(UserController.java:18)
    at Server.processRequest(Server.java:103)
    at Server.main(Server.java:12)

grep avec des regex (-E)

-E active les expressions regulieres etendues (équivalent de egrep) :

bash# Chercher plusieurs mots (OU)
grep -E "error|warning|fatal" app.log

# Chercher un pattern
grep -E "^[0-9]{4}-[0-9]{2}-[0-9]{2}" app.log    # Lignes commencant par une date
grep -E "https?://[^ ]+" readme.md                 # URLs (http ou https)
grep -E "\b[A-Z]{2,}\b" code.ts                    # Mots tout en majuscules

# Chercher une adresse IP
grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" access.log

# Extraire seulement le match (pas la ligne entiere)
grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" access.log | sort -u
# Liste unique des IPs dans les logs

Combiner grep avec des pipes

C'est là où grep devient vraiment puissant :

bash# Filtrer la sortie d'une commande
ps aux | grep "node"
docker ps | grep "running"
env | grep "PATH"

# Enchainer les filtres
cat access.log | grep "POST" | grep -v "healthcheck" | grep "500"
# Requetes POST qui ne sont pas des healthcheck et qui ont un code 500

# Compter les erreurs par heure
grep "ERROR" app.log | awk '{print $2}' | cut -d: -f1 | sort | uniq -c
#  142 08
#  253 09
#   37 10
# 253 erreurs entre 09:00 et 09:59

# Chercher un processus (en excluant le grep lui-meme)
ps aux | grep "[n]ode"
# L'astuce [n]ode : le grep ne se matche pas lui-meme

find : chercher des fichiers

On a vu find dans l'article sur les fichiers. Ici on va plus loin.

Recherches avancees

bash# Par nom avec des patterns
find . -name "*.test.ts"                        # Tests TypeScript
find . -iname "dockerfile*"                      # Insensible a la casse
find . -name "*.ts" -not -name "*.test.ts"      # TS mais pas les tests
find . -name "*.ts" -o -name "*.tsx"            # TS ou TSX (ou logique)

# Par type
find . -type f                    # Fichiers
find . -type d                    # Dossiers
find . -type l                    # Liens symboliques
find . -type f -empty             # Fichiers vides
find . -type d -empty             # Dossiers vides

# Par taille
find . -type f -size +100M        # Plus de 100 Mo
find . -type f -size -1k          # Moins de 1 Ko
find . -type f -size +10M -size -100M  # Entre 10 et 100 Mo

# Par date
find . -mtime 0                   # Modifie aujourd'hui
find . -mtime -7                  # Modifie dans les 7 derniers jours
find . -mtime +30                 # Pas modifie depuis 30 jours
find . -newer reference.txt       # Plus recent que reference.txt
find . -mmin -60                  # Modifie dans la derniere heure

# Par permissions
find . -perm 777                  # Permissions exactement 777 (dangereux)
find . -perm -u+x                # Executables par le proprietaire
find . -not -perm -o+r           # Non lisibles par others

Actions sur les résultats

bash# Supprimer les fichiers trouves
find /tmp -name "*.tmp" -mtime +7 -delete
# Supprime les .tmp de plus de 7 jours dans /tmp

# Executer une commande sur chaque fichier
find . -name "*.sh" -exec chmod +x {} \;
# Rend executable chaque script shell

# Avec + au lieu de \; (plus performant, passe plusieurs fichiers a la fois)
find . -name "*.ts" -exec wc -l {} +
# Compte les lignes de tous les .ts

# Confirmation interactive
find . -name "*.log" -ok rm {} \;
# Demande confirmation avant chaque suppression

Combiner grep et find

Le combo grep + find est extremement puissant :

bash# Chercher "TODO" dans les fichiers TypeScript (en excluant node_modules)
find src -name "*.ts" -exec grep -Hn "TODO" {} +

# Equivalent plus lisible avec xargs
find src -name "*.ts" | xargs grep -Hn "TODO"

# Chercher dans les fichiers modifies cette semaine
find . -name "*.ts" -mtime -7 -exec grep -l "deprecated" {} +

# Trouver les fichiers de config qui contiennent "localhost"
find /etc -name "*.conf" -exec grep -l "localhost" {} + 2>/dev/null

# Remplacer dans tous les fichiers trouves
find src -name "*.ts" -exec sed -i 's/oldApi/newApi/g' {} +

ripgrep (rg) : l'alternative moderne

ripgrep (commande rg) est un grep moderne écrit en Rust. Il est plus rapide, respecte .gitignore par défaut, et a une sortie plus lisible :

bash# Installation
sudo apt install ripgrep      # Debian/Ubuntu
brew install ripgrep           # macOS

# Utilisation basique (recursif par defaut)
rg "TODO" src/
# Pas besoin de -r, pas besoin de --exclude-dir=node_modules
# Il lit .gitignore automatiquement

# Equivalences avec grep
grep -rn "pattern" src/           ->  rg "pattern" src/
grep -ri "pattern" src/           ->  rg -i "pattern" src/
grep -rl "pattern" src/           ->  rg -l "pattern" src/
grep -rn "pattern" --include="*.ts"  ->  rg -t ts "pattern"

# Options specifiques a rg
rg "pattern" -t ts              # Seulement les fichiers TypeScript
rg "pattern" -T test            # Exclure les fichiers de test
rg "pattern" --hidden           # Inclure les fichiers caches
rg "pattern" -g "!*.test.ts"   # Exclure un pattern de fichiers
rg "pattern" -C 3              # 3 lignes de contexte
rg "pattern" --json            # Sortie JSON (pour scripts)
rg "pattern" --stats           # Statistiques de recherche

# Performance
$ time rg "import" --stats
# 2456 matches in 1.2s sur un projet de 50000 fichiers
# grep -r aurait pris 15 secondes sur le meme projet

Sur un gros projet, la différence de vitesse est flagrante. rg ignore automatiquement .git/, node_modules/, target/, et tout ce qui est dans .gitignore. Si tu ne devais installer qu'un seul outil supplementaire, c'est celui-la.

locate : la recherche instantanee

locate utilise une base de donnees pre-indexée. La recherche est quasi instantanee, mais les résultats peuvent etre en retard :

bash# Mettre a jour la base (fait automatiquement par cron, mais tu peux forcer)
sudo updatedb

# Chercher un fichier
locate nginx.conf
# /etc/nginx/nginx.conf
# /etc/nginx/nginx.conf.backup

# Insensible a la casse
locate -i dockerfile

locate est pratique pour les recherches système ("ou est installe postgres ?"), mais inutile pour les fichiers recents (la base n'est pas temps réel).

which, whereis, type : trouver des commandes

bash# which : ou est l'executable ?
$ which node
/usr/local/bin/node

$ which python3
/usr/bin/python3

# whereis : executable + man pages + sources
$ whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx /usr/share/man/man8/nginx.8.gz

# type : comment le shell interprete la commande
$ type ls
ls is aliased to 'ls --color=auto'

$ type cd
cd is a shell builtin

$ type node
node is /usr/local/bin/node

# Utile pour debugger les conflits de PATH
$ type -a python
python is /usr/local/bin/python
python is /usr/bin/python
# Deux versions de python, laquelle est utilisee ?

Cas pratiques de la vraie vie

Quelques recherches que je fais régulièrement :

bash# Trouver toutes les variables d'environnement utilisees dans le code
rg 'process\.env\.\w+' src/ -o --no-filename | sort -u

# Trouver les fichiers les plus gros du projet (hors git et node_modules)
find . -type f -not -path "*/.git/*" -not -path "*/node_modules/*" -exec du -h {} + | sort -rh | head -20

# Chercher un port specifique dans toutes les configs
find /etc -name "*.conf" -exec grep -Hn "8080" {} + 2>/dev/null

# Trouver les imports inutilises (premier indice)
rg "^import" src/ -l | while read f; do
    rg "^import .* from" "$f" -o | sed "s/import //" | sed "s/ from.*//" | while read var; do
        count=$(rg "$var" "$f" -c)
        [ "$count" -le 1 ] && echo "$f: $var possibly unused"
    done
done

# Compter les lignes de code par langage
find . -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.css" \) -not -path "*/node_modules/*" | while read f; do
    echo "$(wc -l < "$f") $f"
done | sort -rn | head -20

Pour des workflows de recherche encore plus avances avec des outils comme fzf et fd, paltemps.fr propose des guides complémentaires.

Résumé

  • grep : -rn pour chercher recursivement, -i pour ignorer la casse, -E pour les regex
  • grep avec contexte : -A (apres), -B (avant), -C (les deux)
  • find : -name + -type + -mtime couvrent 90% des cas, -exec pour agir sur les résultats
  • ripgrep (rg) est plus rapide et respecte .gitignore : installe-le
  • which pour trouver un executable, type pour comprendre comment le shell le voit
  • Combine grep + find + pipes pour des recherches chirurgicales

Precedent : Pipes et redirections | Suivant : Processus et jobs

Sources

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.