J'ai du mal à maîtriser les bases des scripts Bash. Voici ce que j'ai jusqu'à présent:
#!/bin/bash
FILES="/home/john/my directory/*.txt"
for f in "${FILES}"
do
echo "${f}"
done
Tout ce que je veux faire, c'est énumérer tous les .txt
fichiers dans une boucle for
pour que je puisse faire des trucs avec eux. Mais l'espace dans le my directory
et l'astérisque dans *.txt
ne jouent tout simplement pas bien. J'ai essayé de l'utiliser avec et sans guillemets, avec et sans accolades sur les noms de variables et je ne peux toujours pas imprimer tous les .txt
des dossiers.
C'est une chose très basique, mais je continue de me battre parce que je suis fatigué et que je ne peux pas penser correctement.
Qu'est-ce que je fais mal?
J'ai réussi à appliquer le script ci-dessus si mes FICHIERS n'ont pas d'espace ou d'astérisque ... J'ai dû expérimenter avec ou sans l'utilisation de guillemets doubles et d'accolades pour le faire fonctionner. Mais au moment où j'ai à la fois des espaces et un astérisque, ça gâche tout.
Entre guillemets, le *
ne se développera pas dans une liste de fichiers. Pour utiliser un tel caractère générique avec succès, il doit être en dehors des guillemets.
Même si le caractère générique s'est développé, l'expression "${FILES}"
entraînerait une seule chaîne, pas une liste de fichiers.
Une approche qui fonctionnerait serait:
#!/bin/bash
DIR="/home/john/my directory/"
for f in "$DIR"/*.txt
do
echo "${f}"
done
Dans ce qui précède, les noms de fichiers avec des espaces ou d'autres caractères difficiles seront traités correctement.
Une approche plus avancée pourrait utiliser des tableaux bash:
#!/bin/bash
FILES=("/home/john/my directory/"*.txt)
for f in "${FILES[@]}"
do
echo "${f}"
done
Dans ce cas, FILES
est un tableau de noms de fichiers. Les parens entourant la définition en font un tableau. Notez que le *
est en dehors des guillemets. La construction "${FILES[@]}"
est un cas particulier: il s'étendra à une liste de chaînes où chaque chaîne est l'un des noms de fichier. Les noms de fichiers avec des espaces ou d'autres caractères difficiles seront traités correctement.
Bien que l'utilisation de tableaux comme indiqué par John1024 soit beaucoup plus logique, ici, vous pouvez également utiliser l'opérateur split + glob (en laissant une variable scalaire sans guillemets).
Puisque vous ne voulez que la partie glob de cet opérateur, vous devez désactiver la partie split:
#! /bin/sh -
# that also works in any sh, so you don't even need to have or use bash
file_pattern="/home/john/my directory/*.txt"
# all uppercase variables should be reserved for environment variables
IFS='' # disable splitting
for f in $file_pattern # here we're not quoting the variable so
# we're invoking the split+glob operator.
do
printf '%s\n' "$f" # avoid the non-reliable, non-portable "echo"
done
Ce que vous pouvez faire est de ne laisser que les caractères génériques en dehors des guillemets.
Quelque chose comme:
pour un fichier "avec des espaces" * ". txt"
faire
En traitement
terminé
Si les caractères génériques eux-mêmes se développent en espaces, vous devrez utiliser une approche de fichier par ligne, comme utiliser ls -l pour générer la liste des fichiers et utiliser bash read pour obtenir chaque fichier.