2008-10-22 13 views
76

¿Existe alguna manera fácil de cambiar el nombre de un grupo de archivos que ya están contenidos en un directorio, usando Python?Cambio de nombre de archivos por lotes en un directorio

Ejemplo: Tengo un directorio lleno de archivos * .doc y quiero cambiarles el nombre de manera consistente.

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

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

Respuesta

90

Tal cambio de nombre es bastante fácil, por ejemplo, con os y glob módulos:

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)) 

A continuación, puede utilizarlo en su ejemplo como este:

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

El ejemplo anterior convertirá todas *.doc archivos en c:\temp\xx dir a new(%s).doc, donde %s es el nombre base anterior del archivo (sin extensión).

+1

¿Cómo se usa el símbolo '%' en el comando 'os.path.join (dir, titlePattern% title + ext)'? Sé que '%' es para el funcionamiento del módulo y también se usa como operador de formateo. Pero generalmente es seguido por 's' o' f' para especificar el formato. ¿Por qué no hay nada (espacio) inmediatamente después de '%' en dicho comando? –

+3

@ShashankSawant Es de hecho un operador de formateo. Consulte [Operaciones de formato de cadena] (https://docs.python.org/2/library/stdtypes.html#string-formatting) para obtener documentación y uso de la muestra. – DzinX

6

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

Me gusta tener mis archivos de imágenes de música, películas y nombrados de cierta manera. Cuando descargo archivos del Internet , generalmente no siguen mi convención de nomenclatura . Me encontré cambiando manualmente el nombre de cada archivo para que se ajuste a mi estilo . Esto se hizo realmente rápido, así que decidí escribir un programa para hacerlo .

Este programa puede convertir el nombre del archivo a minúsculas, reemplazar cadenas en el nombre del archivo con lo que quieras, y recortar cualquier número de caracteres desde la parte delantera o trasera del nombre de archivo.

El código fuente del programa también está disponible.

+0

me salvó.gracias. –

+1

Lamentablemente, el enlace está roto, ¿alguien sabe dónde está el código fuente? – ryanpcmcquen

20

Si no te importa el uso de expresiones regulares, entonces esta función sería darle tanto poder en renombrar archivos:

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)) 

Así que en tu ejemplo, se podría hacer (asumiendo que es el directorio actual donde los archivos eres):

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

pero también se puede volver a utilizar los nombres de los archivos iniciales:

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

y más.

93

Prefiero escribir líneas pequeñas para cada reemplazo que tengo que hacer en lugar de hacer un código más genérico y complejo. P.ej.:

Esto reemplaza toda subraya con guiones en cualquier archivo que no oculta en el directorio actual

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

Mucho más fácil que los otros métodos. ESTO es el porque me encanta Python. –

+0

Esto es excelente. – warpedspeed

+0

Perdí demasiado tiempo tratando de descubrir por qué mi comando de "cambio de nombre" no funcionaba. ¡Debería haber venido aquí primero! Gran pitón de una sola línea! – Devin

6

He escrito un script en Python, por mi cuenta. Toma como argumentos la ruta del directorio en el que están presentes los archivos y el patrón de nombres que desea usar. Sin embargo, cambia el nombre adjuntando un número incremental (1, 2, 3, etc.) al patrón de nomenclatura otorgado.

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 

Espero que esto funcione para usted.

10

tengo esto que simplemente cambiar el nombre de todos los archivos en subcarpetas de la carpeta

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))) 

estoy reemplazando todas las ocurrencias de old_str con cualquier caso por new_str.

+0

Este código es realmente para usar para reemplazar cualquier parte de un título de un archivo en un directorio. – ShaunO

1
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 
0

como a mí en mi directorio Tengo múltiples subdirectorio, cada subdirectorio tiene un montón de imágenes que desea cambiar todas las imágenes subdirectorios a 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 

(mys son dueños respuesta) https://stackoverflow.com/a/45734381/6329006

1

Tuve un problema similar, pero quería agregar texto al principio del nombre de archivo de todos los archivos en un directorio y usé un método similar. Vea el siguiente ejemplo:

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])) 
Cuestiones relacionadas