Débutant

Maîtriser tableaux Bash et boucles pour plusieurs fichiers

Apprenez à utiliser les tableaux Bash et les boucles for/while pour traiter plusieurs fichiers proprement, sans casse ni erreurs fréquentes.

Maîtriser tableaux Bash et boucles pour plusieurs fichiers
Difficulté
Facile

Traiter plusieurs fichiers en Bash semble simple tant que les noms restent courts, sans espaces ni caractères gênants. Dès qu'un dossier contient des noms plus variés, un script naïf peut casser des chemins, ignorer des fichiers ou agir sur les mauvais éléments.

Ce tutoriel montre une méthode robuste pour débuter avec les tableaux Bash et les boucles for et while. Vous allez manipuler une liste de fichiers, la parcourir proprement et éviter les erreurs classiques liées au découpage des mots.

Prérequis

Il faut disposer d'un shell Bash et d'un terminal Linux. Une connaissance minimale des commandes pwd, ls, mkdir, touch et cat suffit pour suivre les exemples.

Les commandes sont conçues pour être testées dans un dossier temporaire. Travaillez de préférence dans un répertoire de test afin de ne pas modifier des fichiers importants.

Matériel nécessaire

  • Un terminal avec Bash
  • Un dossier de test où créer quelques fichiers
  • Un éditeur de texte en terminal ou graphique

Étapes

  1. Créer un dossier de test et des fichiers d'exemple

    Un ordinateur portable sur un bureau simple, avec une interface de terminal sombre, à côté d’un dossier contenant რამდენიმე fichiers d’exemple représentés par des feuilles et une image, pendant qu’une main utilise le clavier.

    Commencez par isoler vos essais dans un répertoire dédié. Cela permet de tester les boucles sans risque sur vos vrais documents.

    mkdir -p bash-arrays-demo
    cd bash-arrays-demo
    mkdir -p source sauvegarde
    : > "source/rapport 01.txt"
    : > "source/rapport 02.txt"
    : > "source/notes-finales.txt"
    : > "source/image test.png"
    ls -1 source

    La commande : suivie d'une redirection crée des fichiers vides. Vous obtenez ainsi plusieurs noms, dont certains contiennent des espaces, ce qui est utile pour vérifier la robustesse de vos scripts.

  2. Déclarer un premier tableau Bash

    Créez maintenant un script qui stocke explicitement plusieurs chemins dans un tableau. Ouvrez un fichier nommé demo.sh puis saisissez le contenu suivant.

    #!/usr/bin/env bash
    
    fichiers=(
      "source/rapport 01.txt"
      "source/rapport 02.txt"
      "source/notes-finales.txt"
      "source/image test.png"
    )
    
    printf '%s\n' "{fichiers[@]}"

    Rendez ensuite le script exécutable puis lancez-le. Chaque élément du tableau doit s'afficher sur sa propre ligne.

    chmod +x demo.sh
    ./demo.sh
  3. Afficher la taille et les indices du tableau

    Ajoutez quelques lignes à votre script pour voir comment Bash représente le tableau. Cela aide à comprendre ce que la boucle parcourra ensuite.

    #!/usr/bin/env bash
    
    fichiers=(
      "source/rapport 01.txt"
      "source/rapport 02.txt"
      "source/notes-finales.txt"
      "source/image test.png"
    )
    
    printf 'Nombre: %s\n' "{#fichiers[@]}"
    printf 'Premier: %s\n' "{fichiers[0]}"
    printf 'Indices: %s\n' "{!fichiers[@]}"

    {#fichiers[@]} donne le nombre d'éléments. {!fichiers[@]} affiche les indices actuellement utilisés dans le tableau.

  4. Parcourir le tableau avec une boucle for

    Remplacez l'affichage précédent par une boucle for. C'est la forme la plus lisible quand vous avez déjà une liste prête à l'emploi.

    #!/usr/bin/env bash
    
    fichiers=(
      "source/rapport 01.txt"
      "source/rapport 02.txt"
      "source/notes-finales.txt"
      "source/image test.png"
    )
    
    for fichier in "{fichiers[@]}"; do
      printf 'Traitement: %s\n' "$fichier"
    done

    La partie essentielle est "{fichiers[@]}". Avec ces guillemets, chaque élément du tableau reste un élément unique, même si le nom de fichier contient des espaces.

  5. Tester l'existence de chaque fichier avant d'agir

    Avant de copier, renommer ou lire un fichier, vérifiez qu'il existe toujours. C'est une précaution simple qui évite beaucoup d'erreurs de script.

    #!/usr/bin/env bash
    
    fichiers=(
      "source/rapport 01.txt"
      "source/rapport 02.txt"
      "source/notes-finales.txt"
      "source/image test.png"
      "source/introuvable.txt"
    )
    
    for fichier in "{fichiers[@]}"; do
      if [ -e "$fichier" ]; then
        printf 'OK: %s\n' "$fichier"
      else
        printf 'Absent: %s\n' "$fichier"
      fi
    done

    Le test [ -e "$fichier" ] vérifie si le chemin existe. Vous pouvez ainsi filtrer les éléments invalides avant toute action plus sensible.

  6. Copier plusieurs fichiers sans casser leurs noms

    Vue rapprochée d’un ordinateur portable avec une opération de copie de fichiers, accompagnée de deux dossiers représentant la source et la destination, et de plusieurs fichiers d’exemple posés entre les deux.

    Passez à une action concrète en copiant les fichiers valides vers un autre dossier. Vous allez voir que la robustesse dépend surtout des guillemets et des tests.

    #!/usr/bin/env bash
    
    mkdir -p sauvegarde
    
    fichiers=(
      "source/rapport 01.txt"
      "source/rapport 02.txt"
      "source/notes-finales.txt"
      "source/image test.png"
    )
    
    for fichier in "{fichiers[@]}"; do
      if [ -e "$fichier" ]; then
        cp -- "$fichier" sauvegarde/
        printf 'Copié: %s\n' "$fichier"
      fi
    done

    La commande cp -- "$fichier" sauvegarde/ protège l'appel si un nom commence par un tiret. Le traitement reste ainsi plus sûr face à des noms inhabituels.

  7. Remplir un tableau à partir d'un motif de fichiers

    Vous n'êtes pas obligé d'écrire tous les chemins à la main. Bash peut construire un tableau à partir d'un motif simple qui correspond aux fichiers présents.

    #!/usr/bin/env bash
    
    fichiers=(source/*.txt)
    
    printf 'Nombre: %s\n' "{#fichiers[@]}"
    for fichier in "{fichiers[@]}"; do
      printf '%s\n' "$fichier"
    done

    Ce script récupère les chemins se terminant par .txt dans le dossier source. Vous pouvez ensuite appliquer le même schéma de traitement que dans les étapes précédentes.

  8. Parcourir les indices quand vous avez besoin de la position

    Parfois, vous devez connaître non seulement le fichier, mais aussi sa position dans le tableau. Parcourez alors les indices, puis récupérez l'élément correspondant.

    #!/usr/bin/env bash
    
    fichiers=(
      "source/rapport 01.txt"
      "source/rapport 02.txt"
      "source/notes-finales.txt"
    )
    
    for i in "{!fichiers[@]}"; do
      printf 'Index %s => %s\n' "$i" "{fichiers[i]}"
    done

    Cette forme est utile pour numéroter une sortie ou pour comparer des éléments entre eux. Elle reste lisible tant que le traitement dans la boucle reste court.

  9. Lire une liste de fichiers avec une boucle while

    Utilisez une boucle while quand les données arrivent ligne par ligne, par exemple depuis un fichier texte. Créez d'abord une liste d'entrée contrôlée.

    cat > liste.txt <<'EOF'
    source/rapport 01.txt
    source/rapport 02.txt
    source/notes-finales.txt
    source/image test.png
    EOF

    Ajoutez ensuite ce script pour lire la liste sans casser les espaces. La combinaison IFS= read -r est la forme de base à retenir.

    #!/usr/bin/env bash
    
    while IFS= read -r fichier; do
      printf 'Lu: %s\n' "$fichier"
    done < liste.txt
  10. Convertir une lecture ligne à ligne en tableau réutilisable

    Si vous devez relire plusieurs fois la même liste, stockez-la dans un tableau. Vous séparez ainsi la phase de collecte et la phase de traitement.

    #!/usr/bin/env bash
    
    fichiers=()
    
    while IFS= read -r fichier; do
      fichiers+=("$fichier")
    done < liste.txt
    
    printf 'Nombre chargé: %s\n' "{#fichiers[@]}"
    for fichier in "{fichiers[@]}"; do
      printf 'À traiter: %s\n' "$fichier"
    done

    La syntaxe fichiers+=("$fichier") ajoute un élément à la fin du tableau. Vous pouvez ensuite parcourir ce tableau autant de fois que nécessaire.

  11. Filtrer les fichiers par condition dans la boucle

    Ajoutez maintenant une logique simple pour ne traiter qu'un sous-ensemble de fichiers. Par exemple, vous pouvez ne copier que les fichiers .txt.

    #!/usr/bin/env bash
    
    mkdir -p sauvegarde
    
    fichiers=(
      "source/rapport 01.txt"
      "source/rapport 02.txt"
      "source/notes-finales.txt"
      "source/image test.png"
    )
    
    for fichier in "{fichiers[@]}"; do
      case "$fichier" in
        *.txt)
          cp -- "$fichier" sauvegarde/
          printf 'Texte copié: %s\n' "$fichier"
          ;;
        *)
          printf 'Ignoré: %s\n' "$fichier"
          ;;
      esac
    done

    La structure case évite d'empiler plusieurs tests difficiles à relire. Elle devient vite pratique dès qu'il y a plusieurs cas à distinguer.

  12. Compter les succès et les échecs pendant le traitement

    Un ordinateur portable affichant une activité de traitement répétée, avec des fichiers d’exemple posés à côté et deux groupes distincts représentant les réussites et les échecs.

    Un script devient plus utile quand il résume ce qu'il a réellement fait. Ajoutez deux compteurs pour suivre les fichiers traités et les éléments ignorés.

    #!/usr/bin/env bash
    
    ok=0
    absents=0
    fichiers=(
      "source/rapport 01.txt"
      "source/introuvable.txt"
      "source/notes-finales.txt"
    )
    
    for fichier in "{fichiers[@]}"; do
      if [ -e "$fichier" ]; then
        printf 'Traité: %s\n' "$fichier"
        ((ok++))
      else
        printf 'Absent: %s\n' "$fichier"
        ((absents++))
      fi
    done
    
    printf 'Succès: %s | Absents: %s\n' "$ok" "$absents"

    Vous obtenez ainsi un bilan final simple. C'est très utile quand la boucle traite plus de fichiers que ce que vous pouvez vérifier visuellement.

  13. Encapsuler le traitement dans une structure réutilisable

    Quand votre script grandit, isolez l'action répétée dans un bloc clair. Cela rend la boucle plus lisible et limite les duplications de code.

    #!/usr/bin/env bash
    
    copier_si_present() {
      local fichier="$1"
    
      if [ -e "$fichier" ]; then
        cp -- "$fichier" sauvegarde/
        printf 'Copié: %s\n' "$fichier"
      else
        printf 'Absent: %s\n' "$fichier"
      fi
    }
    
    mkdir -p sauvegarde
    fichiers=(
      "source/rapport 01.txt"
      "source/rapport 02.txt"
      "source/introuvable.txt"
    )
    
    for fichier in "{fichiers[@]}"; do
      copier_si_present "$fichier"
    done

    La boucle se contente maintenant d'itérer sur la liste. Toute la logique métier reste regroupée dans une seule structure, plus facile à modifier ensuite.

  14. Vérifier le comportement avec des cas limites simples

    Avant de considérer le script comme fiable, testez quelques situations réalistes. Ajoutez un fichier absent, un nom avec espace et un autre avec extension différente.

    : > "source/extra document.txt"
    : > "source/archive.log"
    ls -1 source

    Relancez ensuite vos scripts de boucle et comparez le résultat à ce que vous attendez. Cette vérification finale vous aide à repérer les erreurs de sélection, de copie ou de comptage.

Erreurs fréquentes & dépannage

L'erreur la plus fréquente consiste à oublier les guillemets autour des expansions de variables et de tableaux. Dès qu'un nom de fichier contient un espace, le shell peut le découper en plusieurs arguments et fausser tout le traitement.

Une autre erreur courante est d'utiliser for fichier in $(cat liste.txt) pour lire une liste. Cette construction découpe le contenu en mots, alors qu'une boucle while IFS= read -r lit proprement chaque ligne.

Beaucoup de débutants appliquent aussi une action sans vérifier que le chemin existe. Un simple test [ -e "$fichier" ] avant la commande principale rend le script plus prévisible et plus sûr.

Enfin, il est facile de lancer une commande sur un mauvais ensemble de fichiers quand on utilise un motif trop large. Affichez toujours la liste sélectionnée avant une opération potentiellement sensible.

Astuces & pour aller plus loin

Commencez toujours par remplacer l'action réelle par un printf qui affiche ce que le script ferait. Cette phase de simulation permet de valider la boucle avant de copier, déplacer ou supprimer quoi que ce soit.

Si vous devez réutiliser plusieurs fois la même liste, chargez-la dans un tableau. Vous pourrez alors compter, filtrer et parcourir les éléments sans relire la source à chaque étape.

Ajoutez un petit résumé final avec des compteurs de succès et d'erreurs. Même dans un script simple, ce bilan donne un retour immédiat sur la qualité du traitement.

Questions fréquentes

Quand choisir for plutôt que while ?

Utilisez for quand vous avez déjà une liste ou un tableau prêt à parcourir. Utilisez while IFS= read -r quand les données arrivent ligne par ligne depuis un fichier ou une entrée standard.

Pourquoi les guillemets sont-ils si importants en Bash ?

Ils empêchent le shell de redécouper un chemin contenant des espaces en plusieurs arguments. Dans ce tutoriel, ils servent surtout à préserver chaque nom de fichier comme une unité complète.

À quoi sert {fichiers[@]} dans un tableau Bash ?

Cette expansion permet de parcourir tous les éléments du tableau. Dans une boucle, la forme "{fichiers[@]}" conserve proprement chaque élément, même avec des espaces.

Pourquoi éviter for fichier in $(cat liste.txt) ?

Parce que cette écriture découpe le contenu en mots selon les séparateurs du shell. Une ligne comme source/image test.png serait alors brisée en plusieurs morceaux.

Faut-il toujours tester l'existence d'un fichier avant d'agir ?

Dès que la liste peut contenir des chemins absents ou obsolètes, c'est une bonne habitude. Un test simple rend le script plus clair et évite des messages d'erreur inutiles.

Conclusion

Vous avez vu comment créer un tableau Bash, le parcourir avec for, lire une liste avec while et traiter plusieurs fichiers sans casser leurs noms. Les points clés sont simples : citer correctement les variables, utiliser IFS= read -r pour la lecture ligne par ligne et tester les chemins avant l'action.

Avec cette base, vous pouvez automatiser des copies, des filtrages et d'autres traitements par lots de façon bien plus fiable. Si vous gardez un dossier de test et une phase d'affichage avant l'action réelle, vos scripts resteront nettement plus sûrs.

Commentaires · Aucun commentaire pour l'instant

Soyez le premier à réagir.

Laisser un commentaire