Cambiar el nombre de varios archivos en un directorio en Python [duplicar]


Esta pregunta ya tiene una respuesta aquí:

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

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

Estoy tratando de usar el os.path.split pero no está funcionando correctamente. También he considerado el uso de manipulaciones de cadenas, pero tampoco he tenido éxito con eso.

Author: poke, 2010-05-03

15 answers

Uso os.rename(src, dst) para cambiar el nombre o mover un archivo o un directorio.

$ ls
cheese_cheese_type.bar  cheese_cheese_type.foo
$ python
>>> import os
>>> for filename in os.listdir("."):
...  if filename.startswith("cheese_"):
...    os.rename(filename, filename[7:])
... 
>>> 
$ ls
cheese_type.bar  cheese_type.foo
 596
Author: Messa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-20 22:07:01

Aquí hay un script basado en tu 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))
 34
Author: bukzor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-03 15:43:08

Suponiendo que ya está en el directorio, y que los "primeros 8 caracteres" de su comentario se mantienen siempre verdaderos. (Aunque "CHEESE_" tiene 7 caracteres... ? En caso afirmativo, cambie el 8 por el 7)

from glob import glob
from os import rename
for fname in glob('*.prj'):
    rename(fname, fname[8:])
 14
Author: darelf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-03 15:54:11

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, no se hace nada al nombre del archivo.

import os
for fileName in os.listdir("."):
    os.rename(fileName, fileName.replace("CHEESE_CHEESE_", "CHEESE_"))
 13
Author: Yogeesh Seralathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-11 23:28:36

Tengo el mismo problema, donde quiero reemplazar el espacio en blanco in any pdf file to a dash -. Pero los archivos estaban en varios subdirectorios. Así que tuve que usar os.walk(). En su caso para múltiples subdirectorios, podría ser algo como esto:

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_', ''))
 8
Author: Aziz Alto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-08 21:15:08

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)

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

 6
Author: krs1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-16 12:03:43

Este tipo de cosas se ajusta perfectamente a IPython, que tiene integración de shell.

In [1] files = !ls
In [2] for f in files:
           newname = process_filename(f)
           mv $f $newname

Nota: para almacenar esto en un script, use la extensión .ipy, y prefije todos los comandos de shell con !.

Véase también: http://ipython.org/ipython-doc/stable/interactive/shell.html

 5
Author: Erik Allik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-24 18:08:21

Parece que su problema está más en determinar el nuevo nombre de archivo en lugar de cambiar el nombre en sí (para lo cual podría usar el sistema operativo.renombrar método).

No está claro a partir de su pregunta cuál es el patrón que desea cambiar el nombre. No hay nada malo con la manipulación de cadenas. Una expresión regular puede ser lo que necesita aquí.

 2
Author: Uri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-03 15:23:15

Aquí hay una solución más general:

Este código se puede usar para eliminar cualquier carácter particular o conjunto de caracteres recursivamente de todos los nombres de archivo dentro de un directorio y reemplazarlos con cualquier otro carácter, conjunto de caracteres o ningún carácter.

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)
 2
Author: nicholas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-25 11:01:23

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

$ renamer --find "/^CHEESE_/" *
 2
Author: Lloyd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-18 09:39:47

Puede usar el sistema operativo.función del sistema para simplificar e invocar a bash para realizar la tarea:

import os
os.system('mv old_filename new_filename')
 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-11 05:06:24

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 con éxito krename, en Windows Total Commander hace el cambio de nombre con expresiones regulares, pero no encontré un equivalente libre decente para OSX, así que terminé escribiendo un script python que funciona recursivamente y por defecto solo imprime los nuevos nombres de archivo sin hacer ningún cambio. Añadir el interruptor' - w ' a actually modifique los nombres de archivo.

#!/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 voltear 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á un simulacro, e imprimirá los nuevos nombres de archivo 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
 1
Author: ccpizza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-16 19:37:49

Importar sistema operativo importar cadena 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 ()

 1
Author: Ted Fuller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-04 19:04:10

¿Qué hay de esto :

import re
p = re.compile(r'_')
p.split(filename, 1) #where filename is CHEESE_CHEESE_TYPE.***
 0
Author: Bandan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-03 15:34:11

Esto funciona para mí.

import os
for afile in os.listdir('.'):
    filename, file_extension = os.path.splitext(afile)
    if not file_extension == '.xyz':
        os.rename(afile, filename + '.abc')
 0
Author: edib,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-16 20:43:41