Renommez plusieurs fichiers dans un répertoire en Python


Answers

Voici un script basé sur votre commentaire le plus récent.

#!/usr/bin/env python
from os import rename, listdir

badprefix = "cheese_"
fnames = listdir('.')

for fname in fnames:
    if fname.startswith(badprefix*2):
        rename(fname, fname.replace(badprefix, '', 1))
Question

Cette question a déjà une réponse ici:

J'essaie de renommer certains fichiers dans un répertoire en utilisant Python.

Dites que j'ai un fichier appelé CHEESE_CHEESE_TYPE.*** et que vous voulez supprimer CHEESE_ afin que mon nom de fichier résultant soit CHEESE_TYPE

J'essaie d'utiliser os.path.split mais cela ne fonctionne pas correctement. J'ai également envisagé d'utiliser des manipulations de cordes, mais je n'ai pas réussi non plus avec ça.




J'ai le même problème, où je veux remplacer l'espace blanc dans un fichier pdf à un tiret - . Mais les fichiers étaient dans plusieurs sous-répertoires. Donc, j'ai dû utiliser os.walk() . Dans votre cas pour plusieurs sous-répertoires, cela pourrait ressembler à ceci:

import os
for dpath, dnames, fnames in os.walk('/path/to/directory'):
    for f in fnames:
        os.chdir(dpath)
        if f.startswith('cheese_'):
            os.rename(f, f.replace('cheese_', ''))



Je cherchais à l'origine une interface graphique qui permettrait de renommer en utilisant des expressions régulières et qui avait un aperçu du résultat avant d'appliquer des changements.

Sous Linux j'ai utilisé avec succès krename , sur Windows Total Commander renomme avec regexes, mais je n'ai trouvé aucun équivalent libre décent pour OSX, donc j'ai fini par écrire un script python qui fonctionne récursivement et par défaut imprime seulement les nouveaux noms de fichiers sans faire changements. Ajoutez le commutateur '-w' pour modifier réellement les noms de fichiers.

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import fnmatch
import sys
import shutil
import re


def usage():
    print """
Usage:
        %s <work_dir> <search_regex> <replace_regex> [-w|--write]

        By default no changes are made, add '-w' or '--write' as last arg to actually rename files
        after you have previewed the result.
        """ % (os.path.basename(sys.argv[0]))


def rename_files(directory, search_pattern, replace_pattern, write_changes=False):

    pattern_old = re.compile(search_pattern)

    for path, dirs, files in os.walk(os.path.abspath(directory)):

        for filename in fnmatch.filter(files, "*.*"):

            if pattern_old.findall(filename):
                new_name = pattern_old.sub(replace_pattern, filename)

                filepath_old = os.path.join(path, filename)
                filepath_new = os.path.join(path, new_name)

                if not filepath_new:
                    print 'Replacement regex {} returns empty value! Skipping'.format(replace_pattern)
                    continue

                print new_name

                if write_changes:
                    shutil.move(filepath_old, filepath_new)
            else:
                print 'Name [{}] does not match search regex [{}]'.format(filename, search_pattern)

if __name__ == '__main__':
    if len(sys.argv) < 4:
        usage()
        sys.exit(-1)

    work_dir = sys.argv[1]
    search_regex = sys.argv[2]
    replace_regex = sys.argv[3]
    write_changes = (len(sys.argv) > 4) and sys.argv[4].lower() in ['--write', '-w']
    rename_files(work_dir, search_regex, replace_regex, write_changes)

Exemple de cas d'utilisation

Je veux inverser des parties d'un nom de fichier de la manière suivante, c'est-à-dire déplacer le bit m7-08 au début du nom de fichier:

# Before:
Summary-building-mobile-apps-ionic-framework-angularjs-m7-08.mp4

# After:
m7-08_Summary-building-mobile-apps-ionic-framework-angularjs.mp4

Cela va effectuer une exécution sèche, et imprimer les nouveaux noms de fichiers sans réellement renommer les fichiers:

rename_files_regex.py . "([^\.]+?)-(m\\d+-\\d+)" "\\2_\\1"

Cela fera le renommage réel (vous pouvez utiliser soit -w ou --write ):

rename_files_regex.py . "([^\.]+?)-(m\\d+-\\d+)" "\\2_\\1" --write



Le code suivant devrait fonctionner. Il prend chaque nom de fichier dans le répertoire courant, si le nom de fichier contient le motif CHEESE_CHEESE_ alors il est renommé. Si ce n'est pas le cas, rien n'est fait pour le nom de fichier.

import os
for fileName in os.listdir("."):
    os.rename(fileName, fileName.replace("CHEESE_CHEESE_", "CHEESE_"))



Il semble que votre problème est plus de déterminer le nouveau nom de fichier plutôt que le renommer lui-même (pour lequel vous pourriez utiliser la méthode os.rename).

Il n'est pas clair à partir de votre question quel est le motif que vous voulez renommer. Il n'y a rien de mal à manipuler la chaîne. Une expression régulière peut être ce dont vous avez besoin ici.




Voici une solution plus générale:

Ce code peut être utilisé pour supprimer un caractère particulier ou un ensemble de caractères récursivement de tous les noms de fichiers dans un répertoire et les remplacer par un autre caractère, un ensemble de caractères ou aucun caractère.

import os

paths = (os.path.join(root, filename)
        for root, _, filenames in os.walk('C:\FolderName')
        for filename in filenames)

for path in paths:
    # the '#' in the example below will be replaced by the '-' in the filenames in the directory
    newname = path.replace('#', '-')
    if newname != path:
        os.rename(path, newname)



import os importation chaîne def rename_files ():

#List all files in the directory
file_list = os.listdir("/Users/tedfuller/Desktop/prank/")
print(file_list)

#Change current working directory and print out it's location
working_location = os.chdir("/Users/tedfuller/Desktop/prank/")
working_location = os.getcwd()
print(working_location)

#Rename all the files in that directory
for file_name in file_list:
    os.rename(file_name, file_name.translate(str.maketrans("","",string.digits)))

rename_files ()




Related