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.

- 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
Créer un dossier de test et des fichiers d'exemple

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 sourceLa 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.Déclarer un premier tableau Bash
Créez maintenant un script qui stocke explicitement plusieurs chemins dans un tableau. Ouvrez un fichier nommé
demo.shpuis 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.shAfficher 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.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" doneLa 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.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 doneLe test
[ -e "$fichier" ]vérifie si le chemin existe. Vous pouvez ainsi filtrer les éléments invalides avant toute action plus sensible.Copier plusieurs fichiers sans casser leurs noms

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 doneLa 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.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" doneCe script récupère les chemins se terminant par
.txtdans le dossiersource. Vous pouvez ensuite appliquer le même schéma de traitement que dans les étapes précédentes.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]}" doneCette 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.
Lire une liste de fichiers avec une boucle while
Utilisez une boucle
whilequand 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 EOFAjoutez ensuite ce script pour lire la liste sans casser les espaces. La combinaison
IFS= read -rest la forme de base à retenir.#!/usr/bin/env bash while IFS= read -r fichier; do printf 'Lu: %s\n' "$fichier" done < liste.txtConvertir 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" doneLa syntaxe
fichiers+=("$fichier")ajoute un élément à la fin du tableau. Vous pouvez ensuite parcourir ce tableau autant de fois que nécessaire.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 doneLa structure
caseévite d'empiler plusieurs tests difficiles à relire. Elle devient vite pratique dès qu'il y a plusieurs cas à distinguer.Compter les succès et les échecs pendant le traitement

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.
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" doneLa 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.
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 sourceRelancez 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.