Ridenominazione batch di file in una directory


102

Esiste un modo semplice per rinominare un gruppo di file già contenuti in una directory, utilizzando Python?

Esempio: ho una directory piena di file * .doc e voglio rinominarli in modo coerente.

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

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

Risposte:


114

Tale ridenominazione è abbastanza semplice, ad esempio con i moduli os e 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))

Potresti quindi usarlo nel tuo esempio in questo modo:

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

L'esempio sopra convertirà tutti i *.docfile in c:\temp\xxdir in new(%s).doc, dove %sè il precedente nome di base del file (senza estensione).


1
Come viene %utilizzato il simbolo nel comando os.path.join(dir, titlePattern % title + ext)? So che %serve per il funzionamento del modulo e viene utilizzato anche come operatore di formattazione. Ma di solito è seguito da so fper specificare il formato. Perché niente (spazio) è subito dopo %nel suddetto comando?
Shashank Sawant

3
@ShashankSawant È davvero un operatore di formattazione. Vedere Operazioni di formattazione delle stringhe per la documentazione e l'utilizzo di esempio.
DzinX

133

Preferisco scrivere piccole righe per ogni sostituzione che devo fare invece di creare un codice più generico e complesso. Per esempio:

Sostituisce tutti i trattini bassi con trattini in qualsiasi file non nascosto nella directory corrente

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

4
Molto più facile degli altri metodi. QUESTO è il motivo per cui amo Python.
Dan Gayle

Ho sprecato troppo tempo oggi cercando di capire perché il mio comando "rinomina" non funzionava - avrei dovuto venire qui prima! Grande battuta pitonica!
Devin

Non funziona perché Windows continua a riordinare i file in ordine alfabetico dopo ciascuno rename:(
ytpillai

4
Eccellente ma funziona solo con una directory senza sub dir.
Hill

se riesci no such file errora ricordare solo os.renamebisogno del percorso completo
Windsooon

22

Se non ti dispiace usare le espressioni regolari, questa funzione ti darà molto potere nel rinominare i file:

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

Quindi nel tuo esempio, potresti fare (supponendo che sia la directory corrente in cui si trovano i file):

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

ma potresti anche tornare ai nomi di file iniziali:

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

e altro ancora.


11

Ho questo per rinominare semplicemente tutti i file nelle sottocartelle della cartella

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

Sto sostituendo tutte le occorrenze di old_str con in ogni caso new_str.


Questo codice è realmente da utilizzare per sostituire qualsiasi parte del titolo di un file in una directory.
geoJshaun

6

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

Mi piace che i miei file di musica, film e immagini vengano denominati in un certo modo. Quando scarico file da Internet, di solito non seguono la mia convenzione di denominazione. Mi sono ritrovato a rinominare manualmente ogni file per adattarlo al mio stile. Questo è invecchiato molto velocemente, quindi ho deciso di scrivere un programma per farlo per me.

Questo programma può convertire il nome del file in tutto minuscolo, sostituire le stringhe nel nome del file con quello che vuoi e tagliare un numero qualsiasi di caratteri dalla parte anteriore o posteriore del nome del file.

È disponibile anche il codice sorgente del programma.


1
Purtroppo il collegamento è interrotto, qualcuno sa dove si trova il codice sorgente?
ryanpcmcquen

6

Ho scritto uno script Python da solo. Prende come argomenti il ​​percorso della directory in cui sono presenti i file e il modello di denominazione che si desidera utilizzare. Tuttavia, rinomina allegando un numero incrementale (1, 2, 3 e così via) al modello di denominazione che dai.

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

Spero che questo funzioni per te.


5

Trovati nella directory in cui devi eseguire la ridenominazione.

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

per "essere nella directory ..." utilizzareos.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 

2

Ho avuto un problema simile, ma volevo aggiungere del testo all'inizio del nome del file di tutti i file in una directory e ho utilizzato un metodo simile. Vedi esempio sotto:

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

1

per quanto riguarda me nella mia directory ho più sottodirectory, ogni sottodirectory ha molte immagini Voglio cambiare tutte le immagini delle sottodirectory in 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

(la mia risposta) https://stackoverflow.com/a/45734381/6329006


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

1

Se desideri modificare i nomi dei file in un editor (come vim), la libreria dei clic viene fornita con il comando click.edit(), che può essere utilizzato per ricevere l'input dell'utente da un editor. Ecco un esempio di come può essere utilizzato per refactoring dei file in una directory.

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

Ho scritto un'applicazione a riga di comando che utilizza la stessa tecnica, ma che riduce la volatilità di questo script e viene fornita con più opzioni, come il refactoring ricorsivo. Ecco il link alla pagina GitHub . Ciò è utile se ti piacciono le applicazioni a riga di comando e sei interessato ad apportare alcune modifiche rapide ai nomi dei file. (La mia applicazione è simile al comando "bulkrename" trovato in ranger ).


1
Sebbene incoraggiamo i collegamenti a risorse esterne, scoraggiamo le risposte di soli collegamenti poiché vengono rese inutilizzabili alla scadenza del collegamento. Aggiorna la tua risposta per includere la risposta alla domanda :)
IT Delinquent

Assolutamente. Modificherò il mio post. Questo è il mio primo contributo, quindi apprezzo la guida!
Jim Shaddix

0

Questo codice funzionerà

La funzione accetta esattamente due argomenti f_patth come percorso per rinominare il file e new_name come nuovo nome per il file.

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.