Filtrer et analyser du texte : grep, cut, sort, wc
Notions théoriques
La philosophie Unix : de petits outils reliés par des tubes
Linux propose de nombreux outils, chacun spécialisé dans une seule tâche : chercher, extraire, trier, compter. L'intérêt vient de leur combinaison, via le tube | déjà rencontré au niveau 1 : la sortie d'une commande devient l'entrée de la suivante. Un script d'administration s'appuie constamment sur ces chaînes d'outils plutôt que de tout réimplémenter.
grep : rechercher un motif
grep "erreur" fichier.log
| Option | Effet |
|---|---|
-i | ignore la casse (majuscules/minuscules) |
-v | inverse : affiche les lignes qui ne contiennent pas le motif |
-c | affiche uniquement le nombre de lignes correspondantes |
-n | affiche le numéro de ligne devant chaque résultat |
-r | recherche récursive dans un dossier |
-l | affiche seulement le nom des fichiers contenant le motif |
-E | active les expressions régulières étendues |
-q | mode silencieux : n'affiche rien, utile dans un if grep -q ... |
if grep -q "ERROR" application.log; then
echo "Des erreurs ont été détectées"
fi
Les motifs de base de grep reprennent les expressions régulières : ^ (début de ligne), $ (fin de ligne), . (un caractère quelconque), [0-9] (un chiffre). Avec -E, on peut combiner davantage : + (une ou plusieurs fois), | (alternative).
cut : extraire une partie de chaque ligne
cut -d':' -f1,3 /etc/passwd
-ddéfinit le séparateur de champs (:ici).-fsélectionne les champs à garder, par numéro (1,3ou1-3).cut -c1-10extrait plutôt par position de caractère, sans notion de champ.
cut n'accepte qu'un seul caractère comme séparateur, et ne gère pas plusieurs espaces consécutifs comme un seul séparateur. Pour un texte dont les colonnes sont alignées par des espaces variables (la sortie de ps par exemple), cut devient vite insuffisant — nous verrons awk en séance 5, bien plus adapté à ce cas.
sort et uniq : trier et dédoublonner
sort -n fichier.txt # tri numérique (au lieu d'alphabétique)
sort -r fichier.txt # ordre inverse
sort -u fichier.txt # tri + suppression des doublons
sort -t':' -k2 fichier.txt # trie sur le 2e champ, séparateur :
sort fichier.txt | uniq -c
uniq ne détecte que les lignes identiques et adjacentes : il ne dédoublonne correctement qu'un flux déjà trié. D'où l'enchaînement quasi systématique sort | uniq, et uniq -c qui compte, en plus, le nombre d'occurrences de chaque ligne.
wc, head, tail : compter et extraire
wc -l fichier.txt # nombre de lignes
wc -w fichier.txt # nombre de mots
wc -c fichier.txt # nombre d'octets
head -n 5 fichier.txt # les 5 premières lignes
tail -n 5 fichier.txt # les 5 dernières lignes
tail -f fichier.log # suit un fichier en continu (utile pour un log qui grossit)
tr permet de transformer caractère par caractère (tr 'a-z' 'A-Z' pour mettre en majuscules) — un outil que vous croiserez occasionnellement, sans qu'il soit indispensable de le maîtriser en détail ici.
find : rechercher des fichiers
find /var/log -name "*.log" -type f -mtime -7
| Option | Effet |
|---|---|
-name "motif" | filtre par nom de fichier |
-type f | uniquement des fichiers (d pour les dossiers) |
-mtime -7 | modifiés il y a moins de 7 jours |
-size +10M | plus gros que 10 Mo |
-maxdepth N | limite la profondeur de recherche |
Pour agir sur chaque résultat, deux approches :
find /tmp -name "*.tmp" -exec rm {} \;
find /tmp -name "*.tmp" -print0 | xargs -0 rm
La première forme (-exec ... {} \;) fonctionne mais lance une commande par fichier trouvé. -print0 combiné à xargs -0 transmet les noms de fichiers séparés par un caractère nul plutôt qu'un espace ou un retour à la ligne — la seule combinaison réellement sûre face à des noms de fichiers contenant des espaces.
Le code de retour d'un pipeline
Une chaîne commande1 | commande2 renvoie, par défaut, le code de retour de la dernière commande uniquement. Si commande1 échoue mais que commande2 (souvent grep ou wc) réussit, $? ne reflète pas l'échec de commande1 — un piège que nous corrigerons avec set -o pipefail en séance 6.
Exemple pratique
#!/bin/bash
# Analyse rapide d'un journal d'accès web (access.log)
echo "Top 5 des adresses IP les plus actives :"
cut -d' ' -f1 access.log | sort | uniq -c | sort -rn | head -5
echo "---"
echo "Nombre d'erreurs 404 :"
grep -c " 404 " access.log
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
Nous enrichissons sauvegarde.sh d'un filtrage intelligent des fichiers à archiver.
Étape 1 — Lister les fichiers récents
find avec ses filtres (-mtime, -size, -name) évite d'écrire soi-même la logique de parcours récursif et de comparaison de dates, source classique d'erreurs.
Étape 2 — Exclure les fichiers indésirables
Exclure les fichiers indésirables directement dans la construction de la liste évite de les traiter inutilement dans les étapes suivantes du script (archivage, calcul de taille...).
Étape 3 — Compter et journaliser
Afficher un compte avant d'agir permet de repérer immédiatement un résultat suspect (0 fichier trouvé, ou au contraire un nombre anormalement élevé) avant que le script ne poursuive.