Je dois renommer des fichiers sur ma carte SD pour pouvoir copier le contenu de plusieurs sous-dossiers sur mon disque dur. Je dois d'abord les trouver par leur extension .MOD
(je peux le faire en utilisant find ./path/*.MOD2
, car ils se trouvent dans des répertoires différents).
J'ai besoin de les renommer car ils ont tous un nom comme MOV001.MOD
, MOV002.MOD
, dans un autre répertoire, d'autres vidéos, mais portant le même nom. Cela a été créé par ma caméra. Après avoir renommé, je pourrais les copier d’une commande sur mon disque dur.
À cause de leurs noms réels, lorsque j'utilise cp ./path/*.MOD new-path
, le résultat serait que j'écrase des fichiers portant le même nom.
Comment puis-je résoudre ça?
Ce petit script renomme les fichiers sans les déplacer
n=0; for files in dir1/*.MOD dir2/*.MOD dir3/*.MOD; do printf -v new "${files/MOV*./%02d.}" "$((++n))"; echo mv -v "$files" "$new"; done
ou plus lisiblement:
#!/bin/bash
n=0
for files in dir1/*.MOD dir2/*.MOD dir3/*.MOD; do
printf -v new "${files/MOV*./%02d.}" "$((++n))"
echo mv -v -- "$files" "$new"
done
Remplacez dir1
etc par les chemins d'accès réels à vos répertoires avec les fichiers
Supprimez echo
(c'est juste pour tester) après avoir vérifié que cela vous donne ce que vous voulez, pour renommer les fichiers.
Ceci numérote les fichiers 01.MOD
, 02.MOD
, etc. Si vous avez plus de 99 fichiers, remplacez %02d
par %03d
pour obtenir 001.MOD
etc.
n=0
Ceci définit simplement n
comme 0
, c'est là que je veux que bash commence à compter.
for files in dir1/*.MOD dir2/*.MOD dir3/*.MOD
Une boucle for
peut exécuter des commandes de manière itérative sur chaque fichier. La syntaxe est for [variable] in [these things I want to do something to] ; do [command(s)] $[variable]; done
J'ai appelé la variable files
et trouvé vos fichiers à l'aide d'un glob: *.MOD
est étendu par le shell à tout fichier dont le nom se termine par .MOD
(*
correspond à tous les caractères)
printf -v new
printf
peut formater les nouveaux numéros avec une largeur fixe pour faciliter le tri. new
est une autre variable - c'est le nouveau nom des fichiers.
"${files/MOV*./%02d.}" "$((++n))"
Référencer la variable files
précédente et remplacer MOV*
(rappelez-vous *
n’importe quel caractère) par le résultat du nombre incrémentant $((++n))
(c’est n
de la première ligne du script, augmentez d’un point chaque fois que la boucle est exécutée sur un fichier) formatée à l’aide du code %02d
qui signifie printf
représente un nombre décimal d’une largeur fixe de deux chiffres 01, 02 etc. Le modèle de recherche et remplacement inclut le .
pour arrêter *
correspondant au nom de fichier complet et donc à la suppression de l'extension.
echo mv -v -- "$files" "$new"
J'ajoute le echo
juste pour le test - cela montre ce qui sera fait au lieu de le faire. Supprimez l'écho lorsque vous êtes satisfait du résultat pour exécuter la commande.
mv
renomme ou déplace des fichiers; sa syntaxe est mv oldname newname
. J'ai ajouté le drapeau -v
qui indique à mv
d'être "prolixe" et de signaler chaque action. J'ai ajouté --
juste pour être sûr - cela indique à mv
de n'accepter aucune autre option, ce qui empêche tout nom de fichier commençant par -
d'être interprété comme une option de la commande - inutile dans votre commande. cas, mais bonne pratique.
Chaque fichier spécifié par la variable files
est mv
ed sous un nom unique créé dans la variable new
. Nous utilisons $
pour faire référence à des variables. Celles-ci doivent être placées entre "guillemets" afin d'empêcher le shell d'effectuer d'autres extensions sur les noms de fichiers. Cela évite que des caractères spéciaux ou des espaces dans les noms de fichiers ne causent des problèmes.
Vous pouvez les copier à partir d'un répertoire récursif (y compris tous les sous-répertoires), rechercher une extension et les renommer en une étape à l'aide du script ci-dessous.
Tiré des scripts que j'utilise pour m'assurer de ne pas écraser les fichiers, lorsque vous les copiez à partir d'un répertoire récursif:
#!/usr/bin/env python3
import os
import shutil
import sys
dr = sys.argv[1]
new_dir = sys.argv[2]
for root, dirs, files in os.walk(dr):
for name in files:
if name.lower().endswith(".mod"): # for your extension
n = 1; name_orig = name
while os.path.exists(new_dir+"/"+name):
name = "duplicate_"+str(n)+"_"+name_orig
n = n+1
newfile = new_dir+"/"+name
shutil.copy(root+"/"+name_orig, newfile)
Copiez le script dans un fichier vide, enregistrez-le sous le nom nodupes.py
, exécutez-le avec les entrées (source) et le répertoire de sortie comme arguments:
python3 /path/to/nodupes.py /path/to/sourcedir /path/to/outputdir
Il renommera les fichiers portant le même nom, comme suit:
Bien sûr, au lieu de duplicate_
, le script peut être modifié pour utiliser n'importe quoi numéroté (ou juste des chiffres).
Une version généralisée, ne recherchant pas une seule extension, serait:
#!/usr/bin/env python3
import os
import shutil
import sys
dr = sys.argv[1]
new_dir = sys.argv[2]
for root, dirs, files in os.walk(dr):
for name in files:
n = 1; name_orig = name
while os.path.exists(new_dir+"/"+name):
name = "duplicate_"+str(n)+"_"+name_orig
n = n+1
newfile = new_dir+"/"+name
shutil.copy(root+"/"+name_orig, newfile)