web-dev-qa-db-fra.com

Renommez des fichiers dans différents répertoires avec le même nom, afin que chacun ait un nom unique (numéroté)

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?

3
Mikulas Kuzmiak

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.


Explication:

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 mved 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.

3
Zanna

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:

enter image description here

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)
1
Jacob Vlijm