Renommez les fichiers dans différents répertoires portant le même nom, chacun ayant un nom unique (numéroté)

3

Je dois renommer les fichiers de 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 sont dans des répertoires différents).

Je dois les renommer car ils ont tous des noms comme MOV001.MOD , MOV002.MOD , dans d'autres répertoires sont d'autres vidéos, mais de même nom. Ceci a été créé par mon appareil photo. Après avoir été renommé, je pouvais les copier par une commande sur mon disque dur.

En raison de leurs noms réels, lorsque j'utilise cp ./path/*.MOD new-path , le résultat serait que je remplace les fichiers portant un nom similaire.

Comment puis-je résoudre ce problème?

    
posée Mikulas Kuzmiak 07.11.2016 - 19:47
la source

2 réponses

3

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 à 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 réellement renommer les fichiers.

Cela 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 , ce qui est la raison pour laquelle bash doit commencer à compter.

for files in dir1/*.MOD dir2/*.MOD dir3/*.MOD

Une boucle for peut exécuter les commandes itérativement 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 en utilisant 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 nombres avec une largeur fixe pour faciliter le tri. new est une autre variable - c'est le nouveau nom des fichiers.

"${files/MOV*./%02d.}" "$((++n))"

Faire référence à la variable files depuis la version précédente et remplacer MOV* (rappelez-vous * est un caractère quelconque) avec le résultat du nombre incrémenté $((++n)) (ceci est n de la première ligne du script, allez) par un à chaque fois que la boucle est exécutée sur un fichier) formaté en utilisant le code %02d qui à printf signifie un nombre décimal d'une largeur fixe de deux chiffres 01, 02 etc. Le motif de recherche et de remplacement inclut . pour arrêter * correspondant à l'intégralité du nom de fichier et ainsi supprimer l'extension.

echo mv -v -- "$files" "$new"

J'ajoute le echo uniquement pour tester - cela montre ce qui sera fait au lieu de le faire réellement. Supprimez l'écho lorsque vous êtes satisfait du résultat pour exécuter la commande.

mv renomme ou déplace les fichiers; sa syntaxe est mv oldname newname . J'ai ajouté l'indicateur -v qui indique à mv d'être "verbeux" et de signaler chaque action. J'ai ajouté -- juste pour être sûr - cela indique à mv de ne pas accepter d'autres options, ce qui empêche que les noms de fichiers commençant par - soient interprétés comme des options pour la commande.

Chaque fichier spécifié par la variable files est mv ed à un nom unique créé dans la variable new . Nous utilisons $ pour référencer les variables et celles-ci doivent être entre "guillemets" pour empêcher le shell d'effectuer d'autres extensions sur les noms de fichiers - ceci empêche les caractères spéciaux ou les espaces dans les noms de fichiers de poser problème.

    
réponse donnée Zanna 07.11.2016 - 20:42
la source
1

Vous pouvez les copier depuis un répertoire récursif (y compris tous les sous-répertoires), rechercher une extension et les renommer en une étape avec le script ci-dessous.

Tiré de scripts que j'utilise pour m'assurer que non ne remplace pas les fichiers, lors de leur copie depuis 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 nodupes.py , exécutez-le avec le répertoire input (source-) et output en tant qu'arguments:

python3 /path/to/nodupes.py /path/to/sourcedir /path/to/outputdir

Il va renommer des fichiers nommés de la même manière, comme:

Bien sûr, au lieu de duplicate_ , le script peut être modifié pour utiliser tout ce qui est numéroté (ou uniquement des nombres).

Une version généralisée, non recherchant 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)
    
réponse donnée Jacob Vlijm 07.11.2016 - 20:32
la source

Lire d'autres questions sur les étiquettes