Bash pour Data Engineers

Bienvenue dans ce module où tu vas apprendre les commandes Bash essentielles pour manipuler des fichiers, automatiser des tâches, et interagir avec ton environnement système — des compétences indispensables pour un Data Engineer !


Prérequis

Niveau Compétence
✅ Requis Avoir suivi le module 01_intro_data_engineering
✅ Requis Avoir accès à un terminal (Linux, Mac, ou Windows avec WSL/Git Bash)

Objectifs du module

À la fin de ce module, tu seras capable de :

  • Naviguer dans l’arborescence de fichiers
  • Manipuler des fichiers et dossiers
  • Filtrer et rechercher dans des données
  • Écrire des scripts Bash pour automatiser des tâches
  • Planifier des jobs avec cron

C’est quoi le langage Bash ?

Bash (abréviation de Bourne Again SHell) est un langage de commande et de script utilisé dans la majorité des systèmes Unix/Linux (et même sous Windows via WSL ou Git Bash).

Il te permet de :

  • Naviguer dans les dossiers
  • Manipuler des fichiers et des données
  • Automatiser des tâches répétitives
  • Écrire des scripts shell pour lancer des traitements de données

Pourquoi c’est utile pour un Data Engineer ?

Cas d’usage Exemple concret
Lancer des pipelines ETL python etl_pipeline.py && echo "Success" \|\| echo "Failed"
Écrire des jobs cron Extraction automatique de données chaque nuit à 2h
Manipuler des fichiers Fusionner 100 fichiers CSV en un seul
Orchestrer des outils Lancer Docker, Spark, ou Airflow depuis un script
Analyser des logs Trouver toutes les erreurs dans les logs du jour

💡 En bref : le Bash est ton couteau suisse pour parler avec ton ordinateur et piloter l’écosystème data.

ℹ️ Le savais-tu ?

Le mot Bash signifie “Bourne Again SHell”, un jeu de mots sur :

  • Le shell Unix original : le Bourne Shell (sh), développé dans les années 1970 par Stephen Bourne
  • L’expression anglaise “born again” = renaître

Bash est donc une nouvelle version améliorée du shell Bourne, libre, puissante, et utilisée par défaut dans la plupart des systèmes Unix/Linux modernes.

📖 Biographie de Stephen R. Bourne sur Wikipedia

Comment accéder à Bash ?

Système Comment y accéder
🐧 Linux Bash est installé par défaut. Ouvre un Terminal
🍎 macOS Ouvre Terminal (Applications → Utilitaires → Terminal)
🪟 Windows Installe WSL (Windows Subsystem for Linux) ou Git Bash

Installation de WSL sur Windows

# Dans PowerShell en administrateur
wsl --install

Après redémarrage, tu auras accès à un terminal Linux complet !

Vérifier ta version de Bash

bash --version

2. Création et manipulation de fichiers

Créer, copier, déplacer, supprimer :

Voir le code
%%bash
# Créer un dossier
mkdir data

# Créer un dossier avec ses parents (pas d'erreur si existe)
mkdir -p data/raw/2024

# Créer un fichier vide
touch data/fichier.csv

# Créer plusieurs fichiers
touch data/file1.csv data/file2.csv data/file3.csv

# Copier un fichier
cp data/fichier.csv data/fichier_backup.csv

# Copier un dossier entier (récursif)
cp -r data/ data_backup/

# Déplacer / Renommer un fichier
mv data/fichier.csv data/nouveau_nom.csv

# Supprimer un fichier
rm data/file1.csv

# Supprimer un dossier vide
rmdir data/raw/2024

# Supprimer un dossier et son contenu (⚠️ DANGEREUX)
rm -r data_backup/

3. Lecture de contenu

Lire, afficher, compter les lignes :

Voir le code
%%bash
# Créons d'abord un fichier exemple
cat << 'EOF' > ventes.csv
date,produit,quantite,prix
2024-01-01,Laptop,5,999.99
2024-01-02,Souris,20,29.99
2024-01-03,Clavier,15,79.99
2024-01-04,Écran,8,299.99
2024-01-05,Laptop,3,999.99
2024-01-06,Souris,25,29.99
2024-01-07,Casque,12,149.99
EOF

echo "✅ Fichier ventes.csv créé"
Voir le code
%%bash
# Affiche le contenu entier
echo "=== cat ==="
cat ventes.csv

echo ""
echo "=== head (3 premières lignes) ==="
head -n 3 ventes.csv

echo ""
echo "=== tail (2 dernières lignes) ==="
tail -n 2 ventes.csv

echo ""
echo "=== wc (comptage) ==="
wc -l ventes.csv    # Nombre de lignes
wc -w ventes.csv    # Nombre de mots
wc -c ventes.csv    # Nombre de caractères

Lire des gros fichiers avec less

Pour les fichiers volumineux, utilise less qui permet de naviguer :

less gros_fichier.csv
Touche Action
ou j Ligne suivante
ou k Ligne précédente
Space Page suivante
b Page précédente
/mot Rechercher “mot”
n Occurrence suivante
q Quitter

4. Recherche & filtrage

Extraire des informations précises — essentiel pour un Data Engineer !

Voir le code
%%bash
echo "=== grep : recherche de motifs ==="

# Rechercher les lignes contenant "Laptop"
echo "Lignes avec 'Laptop':"
grep "Laptop" ventes.csv

echo ""
# Recherche insensible à la casse
echo "Recherche insensible à la casse (-i):"
grep -i "laptop" ventes.csv

echo ""
# Compter le nombre de correspondances
echo "Nombre de lignes avec 'Souris':"
grep -c "Souris" ventes.csv

echo ""
# Afficher les numéros de ligne
echo "Avec numéros de ligne (-n):"
grep -n "99.99" ventes.csv

echo ""
# Inverser la recherche (lignes qui NE contiennent PAS)
echo "Lignes SANS 'Laptop' (-v):"
grep -v "Laptop" ventes.csv
Voir le code
%%bash
echo "=== find : trouver des fichiers ==="

# Créer quelques fichiers pour l'exemple
mkdir -p projet/data projet/scripts
touch projet/data/users.csv projet/data/sales.csv projet/data/old.json
touch projet/scripts/etl.py projet/scripts/utils.py

# Trouver tous les fichiers .csv
echo "Fichiers .csv:"
find projet/ -name "*.csv"

echo ""
# Trouver tous les fichiers .py
echo "Fichiers .py:"
find projet/ -name "*.py"

echo ""
# Trouver les fichiers modifiés dans les dernières 24h
echo "Fichiers modifiés récemment:"
find projet/ -mtime -1 -type f

# Nettoyage
rm -r projet/
Voir le code
%%bash
echo "=== cut : extraire des colonnes ==="

# Extraire la 2ème colonne (produit)
echo "Colonne 'produit':"
cut -d',' -f2 ventes.csv

echo ""
echo "=== sort : trier ==="
# Trier par produit (2ème colonne)
echo "Trié par produit:"
tail -n +2 ventes.csv | sort -t',' -k2

echo ""
echo "=== uniq : valeurs uniques ==="
# Liste des produits uniques
echo "Produits uniques:"
cut -d',' -f2 ventes.csv | tail -n +2 | sort | uniq

echo ""
# Compter les occurrences
echo "Comptage par produit:"
cut -d',' -f2 ventes.csv | tail -n +2 | sort | uniq -c

5. Pipes & redirections

Le pipe (|) est l’outil le plus puissant de Bash : il permet de chaîner des commandes en envoyant la sortie d’une commande vers l’entrée de la suivante.

Voir le code
%%bash
echo "=== Exemples de pipes ==="

# Trouver les ventes de Laptop et compter
echo "Nombre de ventes Laptop:"
cat ventes.csv | grep "Laptop" | wc -l

echo ""
# Top 3 des produits les plus vendus
echo "Top 3 produits (par nombre de lignes):"
cut -d',' -f2 ventes.csv | tail -n +2 | sort | uniq -c | sort -rn | head -3

echo ""
# Pipeline complexe : produits avec prix > 100
echo "Produits avec prix > 100:"
tail -n +2 ventes.csv | awk -F',' '$4 > 100 {print $2, $4}' | sort -u
Voir le code
%%bash
echo "=== Redirections ==="

# Rediriger vers un fichier (écrase)
grep "Laptop" ventes.csv > laptops.txt
echo "Contenu de laptops.txt:"
cat laptops.txt

echo ""
# Ajouter à un fichier (append)
grep "Écran" ventes.csv >> laptops.txt
echo "Après ajout:"
cat laptops.txt

echo ""
# Rediriger les erreurs
ls fichier_inexistant 2> erreurs.log
echo "Erreur capturée:"
cat erreurs.log

# Nettoyage
rm -f laptops.txt erreurs.log

Récapitulatif des redirections

Symbole Description Exemple
> Redirige stdout vers fichier (écrase) echo "hello" > file.txt
>> Redirige stdout vers fichier (ajoute) echo "world" >> file.txt
2> Redirige stderr vers fichier cmd 2> errors.log
&> Redirige stdout ET stderr cmd &> all.log
< Utilise fichier comme entrée wc -l < file.txt
\| Pipe : stdout → stdin suivant cat file \| grep mot

6. Variables et boucles

Automatiser avec des scripts bash :

Voir le code
%%bash
echo "=== Variables ==="

# Déclarer une variable (PAS d'espace autour du =)
nom="Data Engineer"
annee=2024
dossier_data="/home/user/data"

# Utiliser une variable avec $
echo "Bienvenue $nom !"
echo "Nous sommes en $annee"

# Utiliser ${} pour éviter l'ambiguïté
echo "Fichier: ${dossier_data}/ventes.csv"

echo ""
echo "=== Variables d'environnement ==="
echo "Home: $HOME"
echo "User: $USER"
echo "Shell: $SHELL"
echo "Path: $PATH" | cut -c1-50  # Tronqué pour l'affichage
Voir le code
%%bash
echo "=== Boucle for ==="

# Créer des fichiers de test
mkdir -p data_test
touch data_test/jan.csv data_test/feb.csv data_test/mar.csv

# Boucle sur les fichiers CSV
for fichier in data_test/*.csv; do
    echo "Traitement de: $fichier"
    echo "   Nom: $(basename "$fichier")"
done

echo ""
echo "=== Boucle avec séquence ==="
for i in {1..5}; do
    echo "Itération $i"
done

echo ""
echo "=== Boucle while ==="
compteur=1
while [ $compteur -le 3 ]; do
    echo "Compteur: $compteur"
    ((compteur++))
done

# Nettoyage
rm -r data_test/

7. Conditions (if/else)

Prendre des décisions dans tes scripts :

Voir le code
%%bash
echo "=== Conditions de base ==="

# Vérifier si un fichier existe
if [ -f "ventes.csv" ]; then
    echo "✅ Le fichier ventes.csv existe"
else
    echo "❌ Le fichier n'existe pas"
fi

echo ""
# Vérifier si un dossier existe
if [ -d "/tmp" ]; then
    echo "✅ Le dossier /tmp existe"
fi

echo ""
# Comparer des nombres
nb_lignes=$(wc -l < ventes.csv)
echo "Nombre de lignes: $nb_lignes"

if [ $nb_lignes -gt 5 ]; then
    echo "📊 Fichier volumineux (> 5 lignes)"
else
    echo "📄 Petit fichier"
fi

Opérateurs de test

Test fichiers Description
-f fichier Fichier existe
-d dossier Dossier existe
-r fichier Fichier lisible
-w fichier Fichier modifiable
-s fichier Fichier non vide
Test nombres Description
-eq Égal
-ne Différent
-gt Plus grand que
-lt Plus petit que
-ge Plus grand ou égal
-le Plus petit ou égal
Test chaînes Description
= Égal
!= Différent
-z Chaîne vide
-n Chaîne non vide

8. Créer et exécuter un script Bash

Un script Bash est simplement un fichier texte contenant des commandes :

Voir le code
%%bash
# Créer un script complet
cat << 'EOF' > mon_script.sh
#!/bin/bash
# Script de traitement de données
# Auteur: Data Engineer
# Date: 2024

echo "🚀 Démarrage du script"
echo "📅 Date: $(date)"
echo "👤 Utilisateur: $USER"
echo "📂 Dossier: $(pwd)"

# Vérifier si un argument est passé
if [ -z "$1" ]; then
    echo "⚠️ Usage: ./mon_script.sh <nom_fichier>"
    exit 1
fi

echo "📄 Fichier à traiter: $1"
echo "✅ Script terminé"
EOF

# Rendre exécutable
chmod +x mon_script.sh

# Exécuter le script
echo "=== Exécution sans argument ==="
./mon_script.sh

echo ""
echo "=== Exécution avec argument ==="
./mon_script.sh ventes.csv

# Nettoyage
rm mon_script.sh

9. Automatisation avec Cron

Cron permet de planifier l’exécution automatique de scripts — indispensable pour les pipelines ETL !

Format d’une ligne crontab

┌───────────── minute (0 - 59)
│ ┌───────────── heure (0 - 23)
│ │ ┌───────────── jour du mois (1 - 31)
│ │ │ ┌───────────── mois (1 - 12)
│ │ │ │ ┌───────────── jour de la semaine (0 - 6) (dimanche = 0)
│ │ │ │ │
* * * * * commande à exécuter

Exemples courants pour Data Engineers

Expression Description Cas d’usage
0 2 * * * Tous les jours à 2h ETL nocturne
*/15 * * * * Toutes les 15 minutes Monitoring
0 0 * * 0 Chaque dimanche à minuit Rapport hebdomadaire
0 9 1 * * Le 1er de chaque mois à 9h Rapport mensuel
0 */4 * * * Toutes les 4 heures Synchronisation données

Commandes cron

# Éditer la crontab
crontab -e

# Lister les jobs planifiés
crontab -l

# Supprimer tous les jobs
crontab -r

Exemple de crontab pour Data Engineer

# ETL quotidien à 2h du matin
0 2 * * * /home/user/scripts/etl_pipeline.sh >> /var/log/etl.log 2>&1

# Backup des données chaque dimanche à 3h
0 3 * * 0 /home/user/scripts/backup.sh

# Nettoyage des fichiers temporaires chaque jour à 4h
0 4 * * * find /tmp -mtime +7 -delete

💡 Astuce : Utilise crontab.guru pour générer facilement des expressions cron !


Exercice pratique

Instructions

  1. Crée un dossier de travail nommé mon_premier_script

  2. Entre dans ce dossier

  3. Crée un fichier script appelé bonjour.sh

  4. Édite ce fichier et écris un script qui :

    • Affiche “Bonjour Data Engineer 👋”
    • Affiche la date du jour
    • Te souhaite une bonne session
  5. Rends le script exécutable

  6. Crée un sous-dossier nommé data/ et place-y quelques fichiers .csv (même vides)

  7. Ajoute une étape dans le script pour :

    • Afficher tous les fichiers .csv présents dans le dossier data/
    • Pour chaque fichier .csv, afficher son nom avec un message comme :
      👉 “Fichier trouvé : nom_du_fichier.csv ✅”

📌 Quelle structure utiliser ? (indice : boucle for)

✅ Correction

📥 Afficher la correction complète
#!/bin/bash

# 1. 📢 Afficher un message de bienvenue
echo "Bonjour Data Engineer 👋"

# 2. 🗓️ Afficher la date du jour
echo "Date: $(date)"

# 3. 💬 Souhaiter une bonne session
echo "Bonne session de travail 💪"

# 4. 📁 Créer le dossier 'data/' s'il n'existe pas
mkdir -p data

# 5. 🗂️ Créer quelques fichiers de test
touch data/fichier1.csv data/fichier2.csv data/fichier3.csv

# 6. 🔁 Lister les fichiers CSV
echo ""
echo "🔍 Recherche de fichiers CSV dans ./data..."

for fichier in data/*.csv; do
    if [ -f "$fichier" ]; then
        echo "Fichier trouvé : $(basename "$fichier") ✅"
    fi
done

# 7. ✅ Fin du script
echo ""
echo "Traitement terminé ✅"

Cheatsheet Bash – Commandes essentielles

Catégorie Commande Description
Navigation pwd Affiche le chemin actuel
cd dossier/ Se déplacer dans un dossier
ls -lh Liste les fichiers avec détails
Fichiers touch nom.txt Créer un fichier vide
cp fichier.txt dossier/ Copier un fichier
mv fichier.txt nouveau.txt Renommer ou déplacer
rm fichier.txt Supprimer un fichier
Dossiers mkdir dossier/ Créer un dossier
mkdir -p a/b/c Créer avec parents
rm -r dossier/ Supprimer dossier + contenu
Lecture cat fichier.txt Afficher tout le contenu
head -n 10 fichier.txt 10 premières lignes
tail -n 10 fichier.txt 10 dernières lignes
wc -l fichier.txt Compter les lignes
Recherche grep "mot" fichier.txt Rechercher un mot
find . -name "*.csv" Trouver des fichiers
cut -d',' -f1 fichier.csv Extraire une colonne
Pipes cmd1 \| cmd2 Chaîner des commandes
cmd > fichier.txt Rediriger vers fichier
cmd >> fichier.txt Ajouter à un fichier
Scripts chmod +x script.sh Rendre exécutable
./script.sh Lancer un script
Boucles for f in *.csv; do ...; done Boucle sur fichiers
Cron crontab -e Éditer les tâches planifiées
crontab -l Lister les tâches

📥 Télécharger le Bash Cheatsheet PDF (fr)


Erreurs classiques à éviter

❌ Erreur 💥 Conséquence ✅ Bonne pratique
rm -rf / Supprime TOUT le système ! Toujours vérifier le chemin avant rm -rf
$fichier sans guillemets Bug si espaces dans le nom Utiliser "$fichier"
sudo sans réfléchir Écrase des fichiers système Comprendre la commande avant d’utiliser sudo
Script non testé en prod Perte de données Toujours tester en sandbox d’abord
VAR = valeur (avec espaces) Erreur de syntaxe VAR=valeur (sans espaces)
Oublier #!/bin/bash Script peut mal s’exécuter Toujours commencer par le shebang

🧠 Conseil : Avant d’exécuter une commande destructive (rm, mv), utilise echo pour voir ce qui serait affecté :

# Au lieu de :
rm -rf data/*.csv

# D'abord tester avec :
echo data/*.csv

Quiz de fin de module

Réponds aux questions suivantes pour vérifier tes acquis.


❓ Q1. Quelle commande affiche le chemin du dossier courant ?

  1. cd
  2. pwd
  3. ls
  4. path
💡 Voir la réponse

Réponse : bpwd = Print Working Directory


❓ Q2. Que fait la commande rm -rf mon_dossier/ ?

  1. Redémarre l’ordinateur
  2. Réorganise un fichier
  3. Supprime un dossier et son contenu
  4. Reformate le disque
💡 Voir la réponse

Réponse : c-r = récursif, -f = force (sans confirmation)


❓ Q3. Quelle commande affiche les 10 premières lignes d’un fichier ?

  1. head -n 10
  2. cat -10
  3. start 10
  4. top 10
💡 Voir la réponse

Réponse : ahead -n 10 fichier.txt


❓ Q4. Pourquoi écrire "$fichier" au lieu de $fichier ?

  1. Pour que Bash reconnaisse les fichiers CSV
  2. Pour faire du style
  3. Pour éviter les bugs avec les noms contenant des espaces
  4. Ça n’a pas d’importance
💡 Voir la réponse

Réponse : c — Les guillemets protègent les valeurs contenant des espaces


❓ Q5. Que signifie le | (pipe) en Bash ?

  1. Interrompre une commande
  2. Exécuter un script
  3. Envoyer la sortie d’une commande vers l’entrée d’une autre
  4. Créer un fichier temporaire
💡 Voir la réponse

Réponse : c — Le pipe chaîne les commandes : cmd1 | cmd2


❓ Q6. Quelle expression cron exécute un script tous les jours à 2h du matin ?

  1. 2 0 * * *
  2. 0 2 * * *
  3. * 2 * * *
  4. 0 0 2 * *
💡 Voir la réponse

Réponse : b — Format : minute heure jour mois jour_semaine


Mini-projet : Archiver intelligemment des fichiers CSV

Objectif

Créer un script Bash réaliste qui automatise l’archivage de fichiers .csv selon leur ancienneté.

Contexte

Tu travailles dans une équipe data. Chaque jour, des fichiers .csv sont déposés dans un dossier data/.
Tu dois créer un script qui :

  1. Repère tous les fichiers .csv modifiés il y a plus de 7 jours
  2. Les archive dans un fichier .tar.gz nommé archive_YYYYMMDD.tar.gz
  3. Déplace ces fichiers dans un dossier archive/

Contraintes

  • Le script doit fonctionner même si aucun fichier n’est éligible
  • L’archive doit être horodatée automatiquement
  • Le dossier archive/ doit être créé s’il n’existe pas
  • Ajouter du logging pour tracer les actions

✅ Solution du mini-projet

📥 Afficher la solution complète
#!/bin/bash
#
# Script: archive_csv.sh
# Description: Archive les fichiers CSV de plus de 7 jours
# Auteur: Data Engineer
#

# Configuration
DATA_DIR="./data"
ARCHIVE_DIR="./archive"
DAYS_OLD=7
DATE_TAG=$(date +%Y%m%d)
ARCHIVE_NAME="archive_${DATE_TAG}.tar.gz"
LOG_FILE="archive.log"

# Fonction de logging
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log "🚀 Démarrage du script d'archivage"

# Vérifier que le dossier source existe
if [ ! -d "$DATA_DIR" ]; then
    log "❌ Erreur: Le dossier $DATA_DIR n'existe pas"
    exit 1
fi

# Créer le dossier d'archive si nécessaire
mkdir -p "$ARCHIVE_DIR"
log "📁 Dossier d'archive: $ARCHIVE_DIR"

# Trouver les fichiers CSV de plus de 7 jours
OLD_FILES=$(find "$DATA_DIR" -name "*.csv" -mtime +$DAYS_OLD -type f)

# Vérifier s'il y a des fichiers à archiver
if [ -z "$OLD_FILES" ]; then
    log "ℹ️ Aucun fichier CSV de plus de $DAYS_OLD jours trouvé"
    exit 0
fi

# Compter les fichiers
NB_FILES=$(echo "$OLD_FILES" | wc -l)
log "📊 $NB_FILES fichier(s) à archiver"

# Créer l'archive
log "📦 Création de l'archive $ARCHIVE_NAME..."
echo "$OLD_FILES" | tar -czvf "$ARCHIVE_DIR/$ARCHIVE_NAME" -T -

if [ $? -eq 0 ]; then
    log "✅ Archive créée avec succès"
    
    # Déplacer les fichiers archivés
    for file in $OLD_FILES; do
        mv "$file" "$ARCHIVE_DIR/"
        log "   ↳ Déplacé: $(basename "$file")"
    done
    
    log "🎉 Archivage terminé avec succès"
else
    log "❌ Erreur lors de la création de l'archive"
    exit 1
fi

Pour l’utiliser :

chmod +x archive_csv.sh
./archive_csv.sh

Pour l’automatiser avec cron (tous les jours à 3h) :

0 3 * * * /home/user/scripts/archive_csv.sh

📚 Ressources pour aller plus loin

🌐 Sites & outils

📖 Documentation

🎮 Pratique


➡️ Prochaine étape

Maintenant que tu maîtrises Bash, passons à un autre outil essentiel : Git !

👉 Module suivant : 03_git_for_data_engineers — Versionner ton code et collaborer


🎉 Félicitations ! Tu as terminé le module Bash pour Data Engineers.

Retour au sommet