批量重命名目录中的文件

问题:批量重命名目录中的文件

有没有一种简单的方法可以使用Python重命名目录中已包含的一组文件?

示例: 我有一个充满* .doc文件的目录,我想以一致的方式重命名它们。

X.doc->“ new(X).doc”

Y.doc->“ new(Y).doc”

Is there an easy way to rename a group of files already contained in a directory, using Python?

Example: I have a directory full of *.doc files and I want to rename them in a consistent way.

X.doc -> “new(X).doc”

Y.doc -> “new(Y).doc”


回答 0

这样的重命名非常容易,例如使用osglob模块:

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

上面的示例会将dir中的所有*.doc文件都转换c:\temp\xxnew(%s).doc,其中%s是文件的先前基本名称(不带扩展名)。

Such renaming is quite easy, for example with os and glob modules:

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

You could then use it in your example like this:

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

The above example will convert all *.doc files in c:\temp\xx dir to new(%s).doc, where %s is the previous base name of the file (without extension).


回答 1

我更喜欢为每次替换编写一个小的内衬,而不是编写更加通用和复杂的代码。例如:

这会将当前目录中任何非隐藏文件中的所有下划线都用连字符替换

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

I prefer writing small one liners for each replace I have to do instead of making a more generic and complex code. E.g.:

This replaces all underscores with hyphens in any non-hidden file in the current directory

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

回答 2

如果您不介意使用正则表达式,那么此函数将为您提供重命名文件的强大功能:

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

和更多。

If you don’t mind using regular expressions, then this function would give you much power in renaming files:

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

So in your example, you could do (assuming it’s the current directory where the files are):

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

but you could also roll back to the initial filenames:

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

and more.


回答 3

我用它来简单地重命名文件夹的子文件夹中的所有文件

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

我用new_str替换所有出现的old_str情况。

I have this to simply rename all files in subfolders of folder

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

I am replacing all occurences of old_str with any case by new_str.


回答 4

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

我喜欢用某种方式命名我的音乐,电影和图片文件。当我从Internet下载文件时,它们通常不遵循我的命名约定。我发现自己手动重命名每个文件以适合我的风格。这真的很快就过去了,所以我决定编写一个程序为我做。

该程序可以将文件名转换为所有小写字母,将文件名中的字符串替换为所需内容,并从文件名的开头或后面修剪任意数量的字符。

该程序的源代码也可用。

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

I like to have my music, movie, and picture files named a certain way. When I download files from the internet, they usually don’t follow my naming convention. I found myself manually renaming each file to fit my style. This got old realy fast, so I decided to write a program to do it for me.

This program can convert the filename to all lowercase, replace strings in the filename with whatever you want, and trim any number of characters from the front or back of the filename.

The program’s source code is also available.


回答 5

我自己编写了一个python脚本。它以存在文件的目录路径和要使用的命名模式作为参数。但是,它通过给您提供的命名模式附加一个增量数字(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

希望这对您有用。

I’ve written a python script on my own. It takes as arguments the path of the directory in which the files are present and the naming pattern that you want to use. However, it renames by attaching an incremental number (1, 2, 3 and so on) to the naming pattern you give.

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

Hope this works for you.


回答 6

在您需要执行重命名的目录中。

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

Be in the directory where you need to perform the renaming.

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

回答 7

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

回答 8

我有一个类似的问题,但是我想在目录中所有文件的文件名的开头添加文本,并使用类似的方法。请参见下面的示例:

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

I had a similar problem, but I wanted to append text to the beginning of the file name of all files in a directory and used a similar method. See example below:

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

回答 9

至于我在我的目录中我有多个子目录,每个子目录有很多图像,我想将所有子目录图像更改为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

as to me in my directory I have multiple subdir, each subdir has lots of images I want to change all the subdir images to 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 own answer)https://stackoverflow.com/a/45734381/6329006


回答 10

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

回答 11

如果要在编辑器(例如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”命令游侠)。

If you would like to modify file names in an editor (such as vim), the click library comes with the command click.edit(), which can be used to receive user input from an editor. Here is an example of how it can be used to refactor files in a 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])

I wrote a command line application that uses the same technique, but that reduces the volatility of this script, and comes with more options, such as recursive refactoring. Here is the link to the github page. This is useful if you like command line applications, and are interested in making some quick edits to file names. (My application is similar to the “bulkrename” command found in ranger).


回答 12

该代码将起作用

该函数正好使用两个参数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

This code will work

The function exactly takes two arguments f_patth as your path to rename file and new_name as your new name to the 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