file-io Renombra múltiples archivos en un directorio en Python





7 Answers

Aquí hay un script basado en su comentario más reciente.

#!/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))
python file-io file-rename

Esta pregunta ya tiene una respuesta aquí:

Estoy tratando de cambiar el nombre de algunos archivos en un directorio usando Python.

Digamos que tengo un archivo llamado CHEESE_CHEESE_TYPE.*** y quiero eliminar CHEESE_ para que mi nombre de archivo resultante sea CHEESE_TYPE

Estoy intentando usar os.path.split pero no funciona correctamente. También he considerado usar manipulaciones de cuerdas, pero tampoco he tenido éxito con eso.




El siguiente código debería funcionar. Toma cada nombre de archivo en el directorio actual, si el nombre de archivo contiene el patrón CHEESE_CHEESE_ entonces se le cambia el nombre. Si no se hace nada al nombre del archivo.

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



Prueba esto:

import os
import shutil

for file in os.listdir(dirpath):
    newfile = os.path.join(dirpath, file.split("_",1)[1])
    shutil.move(os.path.join(dirpath,file),newfile)

Supongo que no desea eliminar la extensión de archivo, pero puede hacer la misma división con puntos.




Parece que su problema es más para determinar el nuevo nombre de archivo en lugar de cambiar el nombre en sí mismo (para lo cual podría usar el método os.rename).

De su pregunta no queda claro cuál es el patrón que desea cambiar de nombre. No hay nada malo con la manipulación de cuerdas. Una expresión regular puede ser lo que necesitas aquí.




Este comando eliminará la cadena inicial "CHEESE_" de todos los archivos en el directorio actual, usando el renamer :

$ renamer --find "/^CHEESE_/" *



Originalmente estaba buscando alguna GUI que permitiera cambiar el nombre usando expresiones regulares y que tuviera una vista previa del resultado antes de aplicar los cambios.

En Linux, he usado krename con éxito, en Windows Total Commander se renombra con expresiones regulares, pero no encontré un equivalente libre decente para OSX, así que terminé escribiendo un script de Python que funciona de forma recursiva y, por defecto, solo imprime los nuevos nombres de archivo sin hacer ningún cambios Agregue el interruptor '-w' para modificar realmente los nombres de los archivos.

#!/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)

Ejemplo de caso de uso

Quiero cambiar partes de un nombre de archivo de la siguiente manera, es decir, mover el bit m7-08 al principio del nombre de archivo:

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

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

Esto realizará una ejecución en seco e imprimirá los nuevos nombres de archivos sin cambiar el nombre de ningún archivo:

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

Esto hará el cambio de nombre real (puede usar -w o --write ):

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



¿Qué pasa con esto?

import re
p = re.compile(r'_')
p.split(filename, 1) #where filename is CHEESE_CHEESE_TYPE.***



Related