Đổi tên hàng loạt tệp trong thư mục


102

Có cách nào dễ dàng để đổi tên một nhóm tệp đã có trong thư mục bằng Python không?

Ví dụ: Tôi có một thư mục chứa đầy các tệp * .doc và tôi muốn đổi tên chúng theo một cách nhất quán.

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

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

Câu trả lời:


114

Việc đổi tên như vậy khá dễ dàng, ví dụ như với các mô-đun osglobal :

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

Sau đó, bạn có thể sử dụng nó trong ví dụ của mình như sau:

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

Ví dụ trên sẽ chuyển đổi tất cả *.doccác tệp trong c:\temp\xxdir thành new(%s).doc, đâu %slà tên cơ sở trước đó của tệp (không có phần mở rộng).


1
%hiệu được sử dụng trong lệnh os.path.join(dir, titlePattern % title + ext)như thế nào? Tôi biết %là cho hoạt động mô-đun và cũng được sử dụng như một toán tử định dạng. Nhưng thường thì nó được theo sau bởi shoặc fđể chỉ định định dạng. Tại sao không có gì (khoảng trắng) ngay sau %lệnh đã nói?
Shashank Sawant

3
@ShashankSawant Nó thực sự là một toán tử định dạng. Xem Thao tác định dạng chuỗi để biết tài liệu và cách sử dụng mẫu.
DzinX

133

Tôi thích viết một lớp lót nhỏ cho mỗi lần thay thế tôi phải làm thay vì tạo một đoạn mã chung chung và phức tạp hơn. Ví dụ:

Điều này thay thế tất cả các dấu gạch dưới bằng dấu gạch ngang trong bất kỳ tệp không ẩn nào trong thư mục hiện tại

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

4
Vì vậy, dễ dàng hơn nhiều so với các phương pháp khác. Đây là lý do tại sao tôi yêu Python.
Dan Gayle

Đã lãng phí quá nhiều thời gian hôm nay để cố gắng tìm ra lý do tại sao lệnh "đổi tên" của tôi không hoạt động - đáng lẽ phải đến đây trước! Great Pythonic one-liner!
Devin

Không làm việc bởi vì Windows giữ sắp xếp lại các tập tin bằng cách thứ tự chữ cái sau mỗi rename:(
ytpillai

4
Tuyệt vời nhưng nó chỉ hoạt động với một dir mà không có dir phụ.
Hill,

nếu bạn nhận được no such file errorchỉ nhớ os.renamecần đường dẫn đầy đủ
Windsooon

22

Nếu bạn không phiền khi sử dụng biểu thức chính quy, thì hàm này sẽ cung cấp cho bạn nhiều quyền lực trong việc đổi tên tệp:

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

Vì vậy, trong ví dụ của bạn, bạn có thể làm (giả sử đó là thư mục hiện tại chứa các tệp):

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

nhưng bạn cũng có thể quay trở lại tên tệp ban đầu:

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

và hơn thế nữa.


11

Tôi có điều này để chỉ cần đổi tên tất cả các tệp trong thư mục con của thư mục

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

Tôi đang thay thế tất cả các lần xuất hiện của old_str bằng bất kỳ trường hợp nào bằng new_str.


Mã này thực sự được sử dụng để thay thế bất kỳ phần nào của tiêu đề tệp trong thư mục.
geoJshaun

6

Hãy thử: http://www.mattweber.org/2007/03/04/python-script-renamepy/

Tôi thích đặt tên các tệp nhạc, phim và hình ảnh của mình theo một cách nhất định. Khi tôi tải xuống các tệp từ internet, chúng thường không tuân theo quy ước đặt tên của tôi. Tôi tự đổi tên từng tệp theo cách thủ công để phù hợp với phong cách của mình. Điều này thực sự cũ đi nhanh chóng, vì vậy tôi quyết định viết một chương trình để làm điều đó cho tôi.

Chương trình này có thể chuyển đổi tên tệp thành tất cả chữ thường, thay thế các chuỗi trong tên tệp bằng bất kỳ thứ gì bạn muốn và cắt bất kỳ số ký tự nào từ phía trước hoặc phía sau của tên tệp.

Mã nguồn của chương trình cũng có sẵn.


1
Không may link bị hỏng, có ai biết mã nguồn ở đâu không?
ryanpcmcquen 20/12/16

6

Tôi đã viết một tập lệnh python của riêng tôi. Nó lấy làm đối số là đường dẫn của thư mục chứa tệp và kiểu đặt tên mà bạn muốn sử dụng. Tuy nhiên, nó đổi tên bằng cách gắn một số tăng dần (1, 2, 3, v.v.) vào mẫu đặt tên mà bạn đưa ra.

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

Hy vọng điều này làm việc cho bạn.


5

Nằm trong thư mục mà bạn cần thực hiện đổi tên.

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

để "có trong thư mục ..." sử dụngos.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

Tôi gặp sự cố tương tự, nhưng tôi muốn nối văn bản vào đầu tên tệp của tất cả các tệp trong thư mục và sử dụng một phương pháp tương tự. Xem ví dụ bên dưới:

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

đối với tôi trong thư mục của tôi, tôi có nhiều subir, mỗi subir có rất nhiều hình ảnh, tôi muốn thay đổi tất cả các hình ảnh phụ thành 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

(câu trả lời của riêng tôi) 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

Nếu bạn muốn sửa đổi tên tệp trong trình chỉnh sửa (chẳng hạn như vim), thư viện nhấp chuột đi kèm với lệnh click.edit(), có thể được sử dụng để nhận đầu vào của người dùng từ trình chỉnh sửa. Đây là một ví dụ về cách nó có thể được sử dụng để cấu trúc lại các tệp trong một thư mục.

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

Tôi đã viết một ứng dụng dòng lệnh sử dụng kỹ thuật tương tự, nhưng điều đó làm giảm tính biến động của tập lệnh này và đi kèm với nhiều tùy chọn hơn, chẳng hạn như tái cấu trúc đệ quy. Đây là liên kết đến trang github . Điều này hữu ích nếu bạn thích các ứng dụng dòng lệnh và quan tâm đến việc thực hiện một số chỉnh sửa nhanh cho tên tệp. (Ứng dụng của tôi tương tự như lệnh "số lượng lớn" được tìm thấy trong kiểm lâm ).


1
Trong khi chúng tôi khuyến khích các liên kết đến các tài nguyên bên ngoài, chúng tôi không khuyến khích các câu trả lời chỉ có liên kết vì chúng sẽ vô dụng khi liên kết hết hạn. Vui lòng cập nhật câu trả lời của bạn để bao gồm câu trả lời cho câu hỏi :)
CNTT

Chắc chắn rồi. Tôi sẽ chỉnh sửa bài viết của mình. Đây là đóng góp đầu tiên của tôi vì vậy tôi đánh giá cao sự hướng dẫn!
Jim Shaddix,

0

Mã này sẽ hoạt động

Hàm chính xác lấy hai đối số f_patth làm đường dẫn để đổi tên tệp và new_name làm tên mới của bạn cho tệp.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.