web-dev-qa-db-fra.com

Renommer par lots des fichiers d'un répertoire

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 -> "new (X) .doc"

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

86
Nate

Ce changement de nom est assez facile, par exemple avec os et glob modules:

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 convertira tous les fichiers *.doc de c:\temp\xx dir en new(%s).doc, où %s est le nom de base précédent du fichier (sans extension).

97
DzinX

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

Ceci remplace tous les traits de soulignement par des traits d'union dans tout fichier non caché du répertoire en cours.

import os
[os.rename(f, f.replace('_', '-')) for f in os.listdir('.') if not f.startswith('.')]
113
Cesar Canassa

Si cela ne vous dérange pas d'utiliser des expressions régulières, cette fonction vous donnera beaucoup de pouvoir pour renommer des 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 pourriez faire (en supposant que ce soit le répertoire actuel où se trouvent les fichiers):

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

mais vous pouvez aussi revenir aux noms de fichiers initiaux:

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

et plus.

21
tzot

Je dois simplement renommer 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.

11
octoback

J'ai écrit un script python 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 numéro incrémentiel (1, 2, 3, etc.) 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.

6
harisibrahimkv

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

J'aime avoir ma musique, mon film et fichiers d'image nommés d'une certaine manière . Lorsque je télécharge des fichiers depuis le Internet, ils ne suivent généralement pas mon convention de nommage. Je me suis trouvé renommer manuellement chaque fichier pour correspondre à mon style. Cela a vieilli vraiment vite, alors je a décidé d'écrire un programme pour le faire pour moi.

Ce programme peut convertir le nom de fichier à toutes les minuscules, remplacez les chaînes dans le nom de fichier avec ce que vous voulez, et couper n'importe quel nombre de caractères de le recto ou le verso du nom de fichier.

Le code source du programme est également disponible.

6
xsl

Être dans le répertoire où vous devez effectuer le renommage.

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
2
Ajay Chandran

J'avais 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 utiliser une méthode similaire. Voir 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]))
2
Amber Davis
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 
2
frank__aguirre

Si vous souhaitez modifier les noms de fichier dans un éditeur (tel que vim), la bibliothèque click est fournie avec la commande click.edit(), qui peut être utilisée pour recevoir les entrées de l'utilisateur depuis un éditeur. Voici un exemple d'utilisation de ce filtre 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 en ligne de commande qui utilise la même technique, mais qui réduit la volatilité de ce script et qui comporte davantage d'options, telles que le refactoring récursif. Voici le lien vers la page page github . Cela est utile si vous aimez les applications en ligne de commande et souhaitez modifier rapidement les noms de fichiers. (Mon application est similaire à la commande "bulkrename" trouvée dans ranger ).

1
Jim Shaddix

quant à moi dans mon répertoire, j'ai plusieurs sous-répertoires, chaque sous-répertoire contient de nombreuses images. Je souhaite modifier toutes les images de sous-répertoire 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

1
Jayhello
#  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
1
Dan

Ce code fonctionnera

La fonction prend exactement deux arguments f_patth comme chemin pour renommer le fichier et new_name comme nouveau nom pour le 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
0
murthy annavajhula