Comment renommer les fichiers de sauvegarde, en utilisant sa version de sauvegarde comme suffixe au nom de fichier et en le rendant plus masqué
J'ai travaillé avec un grand nombre de fichiers image. Une partie de cela consistait à déplacer tous les types de fichiers image répartis sur plus de 1000 répertoires dans un seul directement. Il y avait beaucoup de photos qui portaient exactement le même nom, mais qui étaient en fait des images différentes. J'ai utilisé le one-liner suivant pour ce faire:
find . -type f -exec mv --backup=t '{}' /media/DATA-HDD/AllImages \;
Je l'ai fait de cette façon pour que toutes les images portant le même nom obtiennent un fichier de sauvegarde caché, au lieu d'écraser. Cela a très bien fonctionné, mais j'ai maintenant un autre problème que je dois résoudre.
Maintenant, j'ai, bien sûr, beaucoup de tuiles qui ressemblent à ceci:
DSC_0616.NEF
DSC_0616.NEF.~1~
DSC_0616.NEF.~2~
Ce que je cherche à faire est d'exécuter une commande (ou un script), qui renommera n'importe lequel de ces fichiers cachés en ajoutant le numéro de sauvegarde comme suffixe au nom du fichier, et supprimera le. ~ [Bu #] ~ pour les rendre uniques noms de fichiers et pas cachés. Alors, comme ça:
DSC_0616.NEF
DSC_0616_1.NEF
DSC_0616_2.NEF
J'ai passé la majeure partie de quelques heures à essayer de faire des recherches pour tenter cela moi-même, mais je ne peux vraiment rien trouver qui puisse m'aider à y arriver qui soit dans mon domaine de connaissances sur le sujet.
Réponses
Tant que vous êtes certain que tout est nommé de manière cohérente comme vous l'avez décrit ci-dessus, certaines expressions régulières peuvent faire le travail via un script shell:
#!/bin/bash
# sets the file separator to be only newlines, in case files have spaces in them
IFS=$'\n' for file in $(find . -type f); do
# parses just the number(s) between two tildes, and only at the end of the file
number=$(echo $file | grep -Eo "~[0-9]+~$" | sed s/'~'/''/g) # if no match found, assume this is a "base" file that does not need to be renamed if [ "$number" == "" ]; then
continue
fi
# parses the file name through "NEF", then deletes ".NEF"
filename=$(echo $file | grep -Eio "^.+\.NEF" | sed s/'\.NEF'/''/g )
if [ "$filename" == "" ]; then continue fi mv -v $file $(echo "$filename"_"$number.NEF") # if anything went wrong, exit immediately if [ "$?" != "0" ]; then
echo "Unable to move file $file"
exit 1
fi
done
Cela fonctionnera également pour la descente dans les répertoires, placez simplement le script et exécutez-le avec votre répertoire de travail en haut de l'arborescence de répertoires de votre projet. Exécution avec des fichiers d'exemple comme vous l'avez fourni:
###@###:~/project$ find . -type f
./DSC_0616.NEF.~8~
./DSC_0616.NEF.~5~
./DSC_0616.NEF.~1~
./DSC_0616.NEF.~7~
./DSC_0616.NEF.~3~
./DSC_0616.NEF.~4~
./DSC_0616.NEF.~9~
./DSC_0616.NEF.~2~
./DSC_0616.NEF.~6~
./lower_dir/DSC_0616.NEF.~8~
./lower_dir/DSC_0616.NEF.~5~
./lower_dir/DSC_0616.NEF.~1~
./lower_dir/DSC_0616.NEF.~7~
./lower_dir/DSC_0616.NEF.~3~
./lower_dir/DSC_0616.NEF.~4~
./lower_dir/DSC_0616.NEF.~9~
./lower_dir/DSC_0616.NEF.~2~
./lower_dir/DSC_0616.NEF.~6~
après avoir exécuté le script:
###@###:~/project$ find . -type f
./DSC_0616_1.NEF
./DSC_0616_3.NEF
./DSC_0616_7.NEF
./DSC_0616_5.NEF
./DSC_0616_2.NEF
./DSC_0616_9.NEF
./DSC_0616_6.NEF
./DSC_0616_8.NEF
./DSC_0616_4.NEF
./lower_dir/DSC_0616_1.NEF
./lower_dir/DSC_0616_3.NEF
./lower_dir/DSC_0616_7.NEF
./lower_dir/DSC_0616_5.NEF
./lower_dir/DSC_0616_2.NEF
./lower_dir/DSC_0616_9.NEF
./lower_dir/DSC_0616_6.NEF
./lower_dir/DSC_0616_8.NEF
./lower_dir/DSC_0616_4.NEF