การเปลี่ยนชื่อไฟล์เป็นกลุ่มในไดเรกทอรี


102

มีวิธีง่ายๆในการเปลี่ยนชื่อกลุ่มไฟล์ที่มีอยู่แล้วในไดเร็กทอรีโดยใช้ Python หรือไม่?

ตัวอย่าง: ฉันมีไดเร็กทอรีที่เต็มไปด้วยไฟล์ * .doc และต้องการเปลี่ยนชื่อให้สอดคล้องกัน

X.doc -> "ใหม่ (X) .doc"

Y.doc -> "ใหม่ (Y) .doc"

คำตอบ:


114

การเปลี่ยนชื่อดังกล่าวค่อนข้างง่ายตัวอย่างเช่นด้วยระบบปฏิบัติการและโมดูลลูกโลก :

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เพื่อระบุรูปแบบ เหตุใดจึงไม่มีอะไร (ช่องว่าง) %ในคำสั่งดังกล่าวทันที
Shashank Sawant

3
@ShashankSawant มันเป็นตัวดำเนินการจัดรูปแบบ ดูการดำเนินการจัดรูปแบบสตริงสำหรับเอกสารประกอบและตัวอย่างการใช้งาน
DzinX

133

ฉันชอบเขียนหนึ่งเส้นเล็ก ๆ สำหรับการแทนที่แต่ละครั้งฉันต้องทำแทนที่จะสร้างรหัสทั่วไปและซับซ้อนมากขึ้น เช่น:

สิ่งนี้จะแทนที่ขีดล่างทั้งหมดด้วยยัติภังค์ในไฟล์ที่ไม่ถูกซ่อนในไดเร็กทอรีปัจจุบัน

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

4
ง่ายกว่าวิธีอื่น ๆ มาก นี่คือเหตุผลที่ฉันรัก Python
Dan Gayle

เสียเวลาไปมากแล้ววันนี้พยายามหาสาเหตุว่าทำไมคำสั่ง "เปลี่ยนชื่อ" ของฉันไม่ทำงาน - ควรมาที่นี่ก่อน! Pythonic หนึ่งซับที่ยอดเยี่ยม!
Devin

ไม่ทำงานเนื่องจาก 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

ฉันเขียนสคริปต์ 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

หวังว่านี่จะเหมาะกับคุณ


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

เป็น "อยู่ในไดเรกทอรี ... " ใช้os.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 มีภาพมากมายที่ฉันต้องการเปลี่ยนภาพย่อยทั้งหมดเป็น 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

หากคุณต้องการแก้ไขชื่อไฟล์ในตัวแก้ไข (เช่นกลุ่ม) ไลบรารีการคลิกจะมาพร้อมกับคำสั่งclick.edit()ซึ่งสามารถใช้เพื่อรับอินพุตของผู้ใช้จากตัวแก้ไข นี่คือตัวอย่างวิธีการใช้ refactor ไฟล์ในไดเร็กทอรี

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

อย่างแน่นอน ฉันจะแก้ไขโพสต์ของฉัน นี่เป็นการมีส่วนร่วมครั้งแรกของฉันดังนั้นฉันจึงขอขอบคุณคำแนะนำ!
Jim Shaddix

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.