Il existe différents points d'échec possibles dans votre script. Tout d'abord, rm *.old*
utilisera le globbing pour créer une liste de tous les fichiers correspondants, et qui peut traiter les noms de fichiers contenant des espaces. Votre script, cependant, attribue une variable à chaque résultat du glob et le fait sans citer. Cela se cassera si vos noms de fichiers contiennent des espaces. Par exemple:
$ ls
'file name with spaces.old.txt' file.old.txt
$ rm *.old.* ## works: both files are deleted
$ touch "file.old.txt" "file name with spaces.old.txt"
$ for i in ./*; do oldfile=$i; rm -v $oldfile; done
rm: cannot remove './file': No such file or directory
rm: cannot remove 'name': No such file or directory
rm: cannot remove 'with': No such file or directory
rm: cannot remove 'spaces.old.txt': No such file or directory
removed './file.old.txt'
Comme vous pouvez le voir, la boucle a échoué pour le fichier avec des espaces dans son nom. Pour le faire correctement, vous devez citer la variable:
$ for i in ./*; do oldfile="$i"; rm -v "$oldfile"; done
removed './file name with spaces.old.txt'
removed './file.old.txt'
Le même problème s'applique à presque toutes les utilisations de $i
votre script. Vous devez toujours citer vos variables .
Le prochain problème possible est que vous semblez vous attendre à ce que les *.old.*
fichiers correspondent à l'extension .old
. Ce n'est pas le cas. Il correspond à "0 ou plusieurs caractères" ( *
), puis à a .
, puis à "old", puis à un autre .
puis à "0 ou plusieurs caractères à nouveau". Cela signifie qu'il ne correspondra pas à quelque chose comme file.old
, mais seulement à quelque chose comme `file.old.foo:
$ ls
file.old file.old.foo
$ for i in *; do if [[ "$i" == *.old.* ]]; then echo $i; fi; done
file.old.foo
Donc, pas d'ennemi de match file.old
. Dans tous les cas, votre script est beaucoup plus complexe que nécessaire. Essayez plutôt celui-ci:
#!/bin/bash
for i in *; do
if [[ -f "$i" ]]; then
if [[ "$i" == *.old ]]; then
rm -v "$i" || echo "rm failed for $i"
else
echo "$i doesn't have an .old extension"
fi
cp -v "$i" "$i".old
else
echo "$i is not a file"
fi
done
Notez que j'ai ajouté -v
aux instructions rm
et cp which does the same thing as what you were doing with your
echo`.
Ce n'est pas parfait car lorsque vous trouvez, par exemple, file.old
cela sera supprimé et, plus tard, le script essaiera de le copier et échouera car le fichier n'existe plus. Cependant, vous n'avez pas expliqué ce que votre script tente réellement de faire, donc je ne peux pas résoudre ce problème pour vous à moins que vous ne nous disiez ce que vous essayez vraiment d'accomplir.
Si vous voulez i) supprimer tous les fichiers avec l' .old
extension et ii) ajouter l' .old
extension à tous les fichiers existants qui ne l'ont pas, tout ce dont vous avez vraiment besoin est:
#!/bin/bash
for i in *.old; do
if [[ -f "$i" ]]; then
rm -v "$i" || echo "rm failed for $i"
else
echo "$i is not a file"
fi
done
## All the ,old files have been removed at this point
## copy the rest
for i in *; do
if [[ -f "$i" ]]; then
## the -v makes cp report copied files
cp -v "$i" "$i".old
fi
done
rm *.old.*
qui supprime ces fichiers mais pas le fichier de sauvegarde file.old. J'essaie de le faire dans mon script. Merci