Пакетне перейменування файлів у каталозі


102

Чи є простий спосіб перейменувати групу файлів, які вже містяться в каталозі, використовуючи Python?

Приклад: У мене каталог, повний файлів * .doc, і я хочу перейменувати їх послідовно.

X.doc -> "новий (X) .doc"

Y.doc -> "новий (Y) .doc"

Відповіді:


114

Таке перейменування є досить простим, наприклад, з os та 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))

Потім ви можете використовувати його у своєму прикладі так:

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

Вищенаведений приклад перетворить усі *.docфайли в c:\temp\xxdir new(%s).doc, де %sпопереднє базове ім'я файлу (без розширення).


1
Як %символ використовується в команді os.path.join(dir, titlePattern % title + ext)? Я знаю %, що для модульної роботи, а також використовується як оператор форматування. Але зазвичай за ним слідує sабо fвказати формат. Чому %в зазначеній команді нічого не відбувається (пробіл) ?
Шашанк Сован

3
@ShashankSawant Це дійсно оператор форматування. Див. Розділ " Операції форматування рядків" щодо документації та використання зразка.
DzinX

133

Я вважаю за краще писати невеликі вкладиші для кожної заміни, яку я повинен зробити, а не робити більш загальний і складний код. Наприклад:

Це замінює усі підкреслення дефісами в будь-якому не прихованому файлі в поточній папці

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

4
Так набагато простіше, ніж інші методи. ЦЕ саме тому я люблю Python.
Ден Гейл

Сьогодні витрачено занадто багато часу, намагаючись з'ясувати, чому моя команда "перейменувати" не спрацювала - мав би прийти сюди першим! Великий пітонічний однолінійний!
Девін

Не працює, оскільки Windows продовжує редагувати файли в алфавітному порядку після кожного rename:(
ytpillai

4
Відмінно, але він працює лише з dir без sub dir.
Пагорб

якщо ви no such file errorпросто пам’ятаєте, os.renameпотрібен повний шлях
Windsooon

22

Якщо ви не проти використовувати регулярні вирази, то ця функція дасть вам багато сил для перейменування файлів:

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

Отже, у вашому прикладі ви можете це зробити (якщо припустити, що це поточний каталог, де знаходяться файли):

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

але ви також можете повернутись до початкових імен файлів:

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

і більше.


11

Я маю це просто перейменувати всі файли в підпапках папки

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

Я замінюю всі випадки old_str будь-яким випадком на new_str.


Цей код дійсно використовувати для заміни будь-якої частини заголовка файлу в каталозі.
geoJshaun

6

Спробуйте: http://www.mattweber.org/2007/03/04/python-script-renamepy/

Мені подобається, щоб мої файли музики, фільму та зображень були названі певним чином. Коли я завантажую файли з Інтернету, вони зазвичай не дотримуються моєї конвенції про іменування. Я знайшов себе вручну перейменувати кожен файл, щоб він міг відповідати моєму стилю. Це старе справді швидко, тому я вирішив написати програму, щоб зробити це для мене.

Ця програма може конвертувати ім'я файлу у всі малі літери, замінювати рядки у імені файлу на все, що завгодно, та обрізати будь-яку кількість символів з передньої чи задньої частини імені файлу.

Також доступний вихідний код програми.


1
На жаль, посилання порушено, хтось знає, де знаходиться вихідний код?
ryanpcmcquen

6

Я написав сценарій пітона самостійно. В якості аргументів він бере шлях до каталогу, в якому є файли, і шаблону іменування, який ви хочете використовувати. Однак він перейменовується, додаючи додаткове число (1, 2, 3 тощо) до даного шаблону іменування.

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

Сподіваюся, це працює для вас.


5

Будьте в каталозі, де потрібно виконати перейменування.

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

to "бути в каталозі ..." useos.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

У мене була схожа проблема, але я хотів додати текст до початку імені файлу всіх файлів у каталозі і застосував аналогічний метод. Дивіться приклад нижче:

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

що стосується мене в моєму каталозі, у мене є декілька subdir, у кожному subdir є багато зображень, я хочу змінити всі зображення subdir на 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

(моя власна відповідь) 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

Якщо ви хочете змінити імена файлів у редакторі (наприклад, vim), бібліотека кліків поставляється з командою click.edit(), яку можна використовувати для отримання вводу користувача від редактора. Ось приклад того, як це можна використовувати для рефакторних файлів у каталозі.

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

Я написав додаток для командного рядка, який використовує ту саму техніку, але це зменшує нестабільність цього сценарію та пропонує більше варіантів, таких як рекурсивний рефакторинг. Ось посилання на сторінку github . Це корисно, якщо вам подобаються програми командного рядка, і ви хочете зробити кілька швидких редагувань для імен файлів. (Моя програма схожа на команду "bulkrename", знайдену в рейнджері ).


1
Хоча ми заохочуємо посилання на зовнішні ресурси, ми відмовляємо відповіді лише для посилань, оскільки вони стають марними, коли термін дії посилання закінчується. Будь ласка, оновіть свою відповідь, щоб включити відповідь на питання :)
IT Delinquent

Зовсім. Я відредагую свою публікацію. Це мій перший внесок, тому я ціную вказівки!
Джим Шаддікс

0

Цей код спрацює

Функція точно приймає два аргументи f_patth як шлях до перейменування файлу та new_name як ваше нове ім'я до файлу.

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.