Aller au contenu principal

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
OptionEffet
-iignore la casse (majuscules/minuscules)
-vinverse : affiche les lignes qui ne contiennent pas le motif
-caffiche uniquement le nombre de lignes correspondantes
-naffiche le numéro de ligne devant chaque résultat
-rrecherche récursive dans un dossier
-laffiche seulement le nom des fichiers contenant le motif
-Eactive les expressions régulières étendues
-qmode 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
  • -d définit le séparateur de champs (: ici).
  • -f sélectionne les champs à garder, par numéro (1,3 ou 1-3).
  • cut -c1-10 extrait plutôt par position de caractère, sans notion de champ.
attention

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
attention

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)
info

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
OptionEffet
-name "motif"filtre par nom de fichier
-type funiquement des fichiers (d pour les dossiers)
-mtime -7modifiés il y a moins de 7 jours
-size +10Mplus gros que 10 Mo
-maxdepth Nlimite 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
attention

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


Pourquoi faut-il un sort avant uniq -c ?


Que fait grep -v erreur fichier.log ?


Que compte exactement wc -l ?


Quel code de retour renvoie commande_qui_echoue | grep motif, par défaut ?


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


Bonne pratique - find plutôt qu'une boucle manuelle

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


Bonne pratique - Filtrer tôt dans le pipeline

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


Bonne pratique - Journaliser les volumes traités

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.

Étape 4 — Le top 3 des plus gros fichiers


Bonne pratique - sort -rh pour des tailles lisibles

sort -h comprend les suffixes lisibles par un humain (K, M, G) produits par du -h, contrairement à sort -n qui les traiterait comme du texte et donnerait un ordre incorrect.

📌 Une solution