问题:批量重命名目录中的文件
有没有一种简单的方法可以使用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
这样的重命名非常容易,例如使用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)')
上面的示例会将dir中的所有*.doc
文件都转换c:\temp\xx
为new(%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
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