Renommer par lots des fichiers dans un répertoire

102

Existe-t-il un moyen simple de renommer un groupe de fichiers déjà contenus dans un répertoire, en utilisant Python?

Exemple: j'ai un répertoire plein de fichiers * .doc et je souhaite les renommer de manière cohérente.

X.doc -> "nouveau (X) .doc"

Y.doc -> "nouveau (Y) .doc"

Nate
la source

Réponses:

114

Un tel changement de nom est assez simple, par exemple avec les modules os et glob :

import glob, os

def rename(dir, pattern, titlePattern):
    for pathAndFilename in glob.iglob(os.path.join(dir, pattern)):
        title, ext = os.path.splitext(os.path.basename(pathAndFilename))
        os.rename(pathAndFilename, 
                  os.path.join(dir, titlePattern % title + ext))

Vous pouvez ensuite l'utiliser dans votre exemple comme ceci:

rename(r'c:\temp\xx', r'*.doc', r'new(%s)')

L'exemple ci - dessus vous permet de convertir tous les *.docfichiers en c:\temp\xxdir new(%s).doc, où %sest le précédent nom de base du fichier (sans extension).

DzinX
la source
1
Comment le %symbole est-il utilisé dans la commande os.path.join(dir, titlePattern % title + ext)? Je sais que %c'est pour le fonctionnement modulo et est également utilisé comme opérateur de formatage. Mais généralement, il est suivi du sou fpour spécifier le format. Pourquoi rien (espace) immédiatement après %dans ladite commande?
Shashank Sawant
3
@ShashankSawant C'est en effet un opérateur de formatage. Voir Opérations de formatage de chaîne pour la documentation et un exemple d'utilisation.
DzinX
133

Je préfère écrire de petites lignes pour chaque remplacement que je dois faire au lieu de créer un code plus générique et complexe. Par exemple:

Cela remplace tous les traits de soulignement par des traits d'union dans tout fichier non caché dans le répertoire courant

import os
[os.rename(f, f.replace('_', '-')) for f in os.listdir('.') if not f.startswith('.')]
Cesar Canassa
la source
4
Tellement plus facile que les autres méthodes. C'est pourquoi j'aime Python.
Dan Gayle
J'ai perdu beaucoup trop de temps aujourd'hui à essayer de comprendre pourquoi ma commande "renommer" ne fonctionnait pas - j'aurais dû venir ici en premier! Grand one-liner pythonique!
Devin
Ne fonctionne pas car Windows continue de réorganiser les fichiers par ordre alphabétique après chaque rename:(
ytpillai
4
Excellent mais cela ne fonctionne qu'avec un répertoire sans sous-répertoire.
Colline du
si vous obtenez no such file errorjuste rappelez-vous os.renamebesoin de chemin complet
Windsooon
22

Si cela ne vous dérange pas d'utiliser des expressions régulières, cette fonction vous donnerait beaucoup de pouvoir pour renommer les fichiers:

import re, glob, os

def renamer(files, pattern, replacement):
    for pathname in glob.glob(files):
        basename= os.path.basename(pathname)
        new_filename= re.sub(pattern, replacement, basename)
        if new_filename != basename:
            os.rename(
              pathname,
              os.path.join(os.path.dirname(pathname), new_filename))

Donc, dans votre exemple, vous pouvez faire (en supposant que c'est le répertoire actuel où se trouvent les fichiers):

renamer("*.doc", r"^(.*)\.doc$", r"new(\1).doc")

mais vous pouvez également revenir aux noms de fichiers initiaux:

renamer("*.doc", r"^new\((.*)\)\.doc", r"\1.doc")

et plus.

tzot
la source
11

J'ai ceci pour renommer simplement tous les fichiers dans les sous-dossiers du dossier

import os

def replace(fpath, old_str, new_str):
    for path, subdirs, files in os.walk(fpath):
        for name in files:
            if(old_str.lower() in name.lower()):
                os.rename(os.path.join(path,name), os.path.join(path,
                                            name.lower().replace(old_str,new_str)))

Je remplace toutes les occurrences de old_str par n'importe quel cas par new_str.

Kiriloff
la source
Ce code est vraiment à utiliser pour remplacer n'importe quelle partie du titre d'un fichier dans un répertoire.
geoJshaun
6

Essayez: http://www.mattweber.org/2007/03/04/python-script-renamepy/

J'aime que mes fichiers de musique, de films et d'images soient nommés d'une certaine manière. Lorsque je télécharge des fichiers sur Internet, ils ne respectent généralement pas ma convention de dénomination. Je me suis retrouvé à renommer manuellement chaque fichier pour l'adapter à mon style. Cela a vieilli très vite, alors j'ai décidé d'écrire un programme pour le faire pour moi.

Ce programme peut convertir le nom de fichier en minuscules, remplacer les chaînes du nom de fichier par ce que vous voulez et couper n'importe quel nombre de caractères à l'avant ou à l'arrière du nom de fichier.

Le code source du programme est également disponible.

xsl
la source
1
Malheureusement, le lien est rompu, est-ce que quelqu'un sait où se trouve le code source?
ryanpcmcquen
6

J'ai écrit un script python par moi-même. Il prend comme arguments le chemin du répertoire dans lequel les fichiers sont présents et le modèle de dénomination que vous souhaitez utiliser. Cependant, il renomme en attachant un nombre incrémentiel (1, 2, 3 et ainsi de suite) au modèle de dénomination que vous donnez.

import os
import sys

# checking whether path and filename are given.
if len(sys.argv) != 3:
    print "Usage : python rename.py <path> <new_name.extension>"
    sys.exit()

# splitting name and extension.
name = sys.argv[2].split('.')
if len(name) < 2:
    name.append('')
else:
    name[1] = ".%s" %name[1]

# to name starting from 1 to number_of_files.
count = 1

# creating a new folder in which the renamed files will be stored.
s = "%s/pic_folder" % sys.argv[1]
try:
    os.mkdir(s)
except OSError:
    # if pic_folder is already present, use it.
    pass

try:
    for x in os.walk(sys.argv[1]):
        for y in x[2]:
            # creating the rename pattern.
            s = "%spic_folder/%s%s%s" %(x[0], name[0], count, name[1])
            # getting the original path of the file to be renamed.
            z = os.path.join(x[0],y)
            # renaming.
            os.rename(z, s)
            # incrementing the count.
            count = count + 1
except OSError:
    pass

J'espère que cela fonctionne pour toi.

harisibrahimkv
la source
5

Soyez dans le répertoire où vous devez effectuer le changement de nom.

import os
# get the file name list to nameList
nameList = os.listdir() 
#loop through the name and rename
for fileName in nameList:
    rename=fileName[15:28]
    os.rename(fileName,rename)
#example:
#input fileName bulk like :20180707131932_IMG_4304.JPG
#output renamed bulk like :IMG_4304.JPG
Ajay Chandran
la source
pour "être dans le répertoire ..." utiliseros.chdir(path_of_directory)
MagTun
2
directoryName = "Photographs"
filePath = os.path.abspath(directoryName)
filePathWithSlash = filePath + "\\"

for counter, filename in enumerate(os.listdir(directoryName)):

    filenameWithPath = os.path.join(filePathWithSlash, filename)

    os.rename(filenameWithPath, filenameWithPath.replace(filename,"DSC_" + \
          str(counter).zfill(4) + ".jpg" ))

# e.g. filename = "photo1.jpg", directory = "c:\users\Photographs"        
# The string.replace call swaps in the new filename into 
# the current filename within the filenameWitPath string. Which    
# is then used by os.rename to rename the file in place, using the  
# current (unmodified) filenameWithPath.

# os.listdir delivers the filename(s) from the directory
# however in attempting to "rename" the file using os 
# a specific location of the file to be renamed is required.

# this code is from Windows 
frank__aguirre
la source
2

J'ai eu un problème similaire, mais je voulais ajouter du texte au début du nom de fichier de tous les fichiers d'un répertoire et j'ai utilisé une méthode similaire. Voir l'exemple ci-dessous:

folder = r"R:\mystuff\GIS_Projects\Website\2017\PDF"

import os


for root, dirs, filenames in os.walk(folder):


for filename in filenames:  
    fullpath = os.path.join(root, filename)  
    filename_split = os.path.splitext(filename) # filename will be filename_split[0] and extension will be filename_split[1])
    print fullpath
    print filename_split[0]
    print filename_split[1]
    os.rename(os.path.join(root, filename), os.path.join(root, "NewText_2017_" + filename_split[0] + filename_split[1]))
Amber Davis
la source
1

quant à moi dans mon répertoire j'ai plusieurs sous-répertoires, chaque sous-répertoire a beaucoup d'images Je veux changer toutes les images de sous-répertoires en 1.jpg ~ n.jpg

def batch_rename():
    base_dir = 'F:/ad_samples/test_samples/'
    sub_dir_list = glob.glob(base_dir + '*')
    # print sub_dir_list # like that ['F:/dir1', 'F:/dir2']
    for dir_item in sub_dir_list:
        files = glob.glob(dir_item + '/*.jpg')
        i = 0
        for f in files:
            os.rename(f, os.path.join(dir_item, str(i) + '.jpg'))
            i += 1

(ma propre réponse) https://stackoverflow.com/a/45734381/6329006

Jayhello
la source
1
#  another regex version
#  usage example:
#  replacing an underscore in the filename with today's date
#  rename_files('..\\output', '(.*)(_)(.*\.CSV)', '\g<1>_20180402_\g<3>')
def rename_files(path, pattern, replacement):
    for filename in os.listdir(path):
        if re.search(pattern, filename):
            new_filename = re.sub(pattern, replacement, filename)
            new_fullname = os.path.join(path, new_filename)
            old_fullname = os.path.join(path, filename)
            os.rename(old_fullname, new_fullname)
            print('Renamed: ' + old_fullname + ' to ' + new_fullname
Dan
la source
1

Si vous souhaitez modifier les noms de fichiers dans un éditeur (tel que vim), la bibliothèque de clics est fournie avec la commande click.edit(), qui peut être utilisée pour recevoir les entrées utilisateur d'un éditeur. Voici un exemple de la façon dont il peut être utilisé pour refactoriser des fichiers dans un répertoire.

import click
from pathlib import Path

# current directory
direc_to_refactor = Path(".")

# list of old file paths
old_paths = list(direc_to_refactor.iterdir())

# list of old file names
old_names = [str(p.name) for p in old_paths]

# modify old file names in an editor,
# and store them in a list of new file names
new_names = click.edit("\n".join(old_names)).split("\n")

# refactor the old file names
for i in range(len(old_paths)):
    old_paths[i].replace(direc_to_refactor / new_names[i])

J'ai écrit une application de ligne de commande qui utilise la même technique, mais qui réduit la volatilité de ce script, et est livrée avec plus d'options, telles que la refactorisation récursive. Voici le lien vers la page github . Ceci est utile si vous aimez les applications en ligne de commande et souhaitez apporter des modifications rapides aux noms de fichiers. (Mon application est similaire à la commande "bulkrename" trouvée dans ranger ).

Jim Shaddix
la source
1
Alors que nous encourageons les liens vers des ressources externes, nous décourageons les réponses de lien uniquement car elles sont rendues inutiles lorsque le lien expire. Veuillez mettre à jour votre réponse pour inclure la réponse à la question :)
IT Delinquent
Absolument. Je vais éditer mon message. C'est ma première contribution donc j'apprécie les conseils!
Jim Shaddix
0

Ce code fonctionnera

La fonction prend exactement deux arguments f_patth comme chemin pour renommer le fichier et new_name comme nouveau nom du fichier.

import glob2
import os


def rename(f_path, new_name):
    filelist = glob2.glob(f_path + "*.ma")
    count = 0
    for file in filelist:
        print("File Count : ", count)
        filename = os.path.split(file)
        print(filename)
        new_filename = f_path + new_name + str(count + 1) + ".ma"
        os.rename(f_path+filename[1], new_filename)
        print(new_filename)
        count = count + 1
murthy annavajhula
la source