วิธีการเปลี่ยนชื่อไฟล์โดยใช้ Python


คำตอบ:


578

การใช้os.rename:

import os

os.rename('a.txt', 'b.kml')

52
ควรสังเกตว่าหากไฟล์ไม่ได้อยู่ในไดเรกทอรีการทำงานคุณจะต้องมีเส้นทางแบบเต็ม
EndermanAPM

ไม่ได้จริงๆบน 3.7 ubuntu ใช้งานได้สำหรับฉันโดยใช้เส้นทางที่เกี่ยวข้อง
toing_toing

2
@toing_to แน่นอนว่ามันทำงานได้เขาอาจหมายความว่าคุณควรทราบถึงไดเรกทอรีปัจจุบันและระบุเส้นทางที่สัมพันธ์กับมันหรือใช้เส้นทางสัมบูรณ์ (เช่นC:/folder/file.txtบน Windows หรือ/home/file.txtLinux / MacOS)
Alex P.

เป็นที่น่าสังเกตว่าสิ่งนี้จะเขียนทับไฟล์ในระบบเหมือน Unix อย่างเงียบ ๆ แต่ล้มเหลวOSErrorในระบบ Windows os.path.existsควรใช้เพื่อตรวจสอบว่ามีเป้าหมายอยู่ก่อนการเปลี่ยนชื่อหรือไม่ สิ่งนี้จะสร้างบั๊ก "เวลาในการตรวจสอบกับเวลาใช้งาน" แต่ก็ไม่น่าจะทำให้เกิดปัญหา (ฉันรู้ว่าไม่มีวิธีง่ายๆรอบนี้ - ดูที่นี่ .
AnnanFay

2
หากผู้ใช้ต้องการให้ไฟล์ถูกแทนที่ในระบบปฏิบัติการใด ๆ ผู้ใช้ควรใช้os.replace
LucG

73

ไฟล์อาจอยู่ในไดเรกทอรีในกรณีนั้นให้ระบุเส้นทาง:

import os
old_file = os.path.join("directory", "a.txt")
new_file = os.path.join("directory", "b.kml")
os.rename(old_file, new_file)

49
import shutil

shutil.move('a.txt', 'b.kml')

สิ่งนี้จะทำงานเพื่อเปลี่ยนชื่อหรือย้ายไฟล์


32
shutil.moveไม่ใช่ตัวเลือกที่ดีเนื่องจากไม่มีการใช้งานแบบปรมาณู ตัวอย่างเช่นหากไฟล์เปิดอยู่shutil.moveจะสร้างไฟล์ด้วยnew_nameแต่จะไม่ลบไฟล์ด้วยold_nameเหตุนี้จึงทำให้คุณมีสองไฟล์ os.renameบนมืออื่น ๆ จะทำอะไรซึ่งเป็นตัวเลือกที่ดี ด้วยshutil.moveแม้ว่าคุณจะจับข้อผิดพลาดคุณยังจะต้องกังวลเกี่ยวกับการตรวจสอบและลบไฟล์โกง ก็ไม่คุ้มค่าเมื่อเป็นเครื่องมือที่ดีกว่าที่มีอยู่: os.rename
mvbentes

34

ในฐานะของ Python 3.4 เราสามารถใช้โมดูลpathlibเพื่อแก้ปัญหานี้ได้

หากคุณอยู่ในเวอร์ชันที่เก่ากว่าคุณสามารถใช้เวอร์ชัน backported ได้ที่นี่

สมมติว่าคุณไม่ได้อยู่ในเส้นทางราก (เพียงเพิ่มความยากนิดหน่อย) คุณต้องการเปลี่ยนชื่อและต้องระบุเส้นทางแบบเต็มเราสามารถดูได้ที่:

some_path = 'a/b/c/the_file.extension'

ดังนั้นคุณสามารถใช้เส้นทางของคุณและสร้างPathวัตถุจากมัน:

from pathlib import Path
p = Path(some_path)

เพียงเพื่อให้ข้อมูลบางอย่างเกี่ยวกับวัตถุนี้ที่เรามีตอนนี้เราสามารถแยกสิ่งต่าง ๆ ออกมาจากวัตถุ ตัวอย่างเช่นถ้าด้วยเหตุผลใดก็ตามที่เราต้องการเปลี่ยนชื่อไฟล์โดยการแก้ไขชื่อไฟล์จากthe_fileเป็นthe_file_1แล้วเราจะได้รับส่วนชื่อไฟล์:

name_without_extension = p.stem

และยังคงมีส่วนขยายอยู่ในมือเช่นกัน:

ext = p.suffix

เราสามารถทำการแก้ไขด้วยการจัดการสตริงอย่างง่าย ๆ :

Python 3.6 และสูงกว่าใช้ประโยชน์จาก f-strings!

new_file_name = f"{name_without_extension}_1"

มิฉะนั้น:

new_file_name = "{}_{}".format(name_without_extension, 1)

และตอนนี้เราสามารถทำการเปลี่ยนชื่อของเราได้โดยการเรียกใช้renameเมธอดบนวัตถุพา ธ ที่เราสร้างและต่อท้ายextเพื่อทำให้โครงสร้างการเปลี่ยนชื่อที่เหมาะสมที่เราต้องการ:

p.rename(Path(p.parent, new_file_name + ext))

อีกไม่นานเพื่อแสดงความเรียบง่าย:

Python 3.6+:

from pathlib import Path
p = Path(some_path)
p.rename(Path(p.parent, f"{p.stem}_1_{p.suffix}"))

รุ่นที่น้อยกว่า Python 3.6 ใช้วิธีการจัดรูปแบบสตริงแทน:

from pathlib import Path
p = Path(some_path)
p.rename(Path(p.parent, "{}_{}_{}".format(p.stem, 1, p.suffix))

3
ทำไมคุณถึงทำเช่นนี้แทนที่จะตอบรับ? ดูเหมือนจะซับซ้อนกว่านี้อีก
rbennell

19
ดี @ rbennell คำตอบส่วนใหญ่คือคำอธิบาย คำตอบนั้นเป็นแค่สามบรรทัดในตอนท้าย นอกจากนี้คำตอบที่ได้รับการยอมรับจะทำอย่างชัดเจนสำหรับการเปลี่ยนชื่อมาก คำตอบนี้ให้วิธีการแสดงวิธีที่คุณสามารถจัดการชื่อไฟล์เพื่อรักษาส่วนต่าง ๆ ที่คุณต้องการในพา ธ หรือชื่อของไฟล์ นอกจากนี้ยังpathlibมีการแนะนำไลบรารี่ใน python 3.4 เพื่อแบ่งปันคำตอบที่นี่นอกจากนี้ยังมีการเปิดรับโมดูลที่เป็นของแข็งเพื่อแสดงความเก่งกาจและการใช้งานสำหรับความต้องการที่ซับซ้อนมากขึ้น
idjaw

4
ขอบคุณ @idjaw ความคิดเห็นของคุณเป็นคำตอบที่ดีสำหรับคำถามพื้นฐานของผู้เริ่มต้นง่ายๆทำไมคุณทำอย่างนั้น? . นอกจากนี้ยังมีการรีเฟรชที่จะเห็นวิธีการที่ไม่เป็นมิตรบนอินเทอร์เน็ตกับสิ่งที่ถือว่าเป็นไม่รู้
Igor V.

3
@SasukeUchiha - เดอะ{}สำหรับสตริงการจัดรูปแบบซึ่งคุณสามารถอ่านข้อมูลเกี่ยวกับที่นี่ ในที่สุดสิ่งที่เกิดขึ้นคือการ{}แทนที่ด้วยตัวแปรที่ส่งผ่านไปยังformatวิธีการ ดังนั้นก่อนที่{}จะถือสิ่งที่อยู่ในและที่สองจะถืออาร์กิวเมนต์ที่สองซึ่งเป็นเพียงname_without_extension 1
idjaw

3
การใช้ f-strings ทำให้มันง่ายยิ่งขึ้น จาก pathlib การนำเข้า Path p = Path (some_path) version = 1 p.rename (Path (p.parent, f "{p.stem} _ {version}" + p.suffix))
Liquidgenius


8

os.renameใช้ แต่คุณต้องผ่านเส้นทางแบบเต็มของไฟล์ทั้งสองไปยังฟังก์ชั่น หากฉันมีไฟล์a.txtบนเดสก์ท็อปของฉันฉันจะทำและฉันก็ต้องให้ไฟล์ที่ถูกเปลี่ยนชื่อด้วยเช่นกัน

 os.rename('C:\\Users\\Desktop\\a.txt', 'C:\\Users\\Desktop\\b.kml')

1
"ต้อง" ไม่เป็นความจริง คุณสามารถแทนที่ชื่อไฟล์ที่สัมพันธ์กันสำหรับชื่อไฟล์แบบสัมบูรณ์และในทางกลับกัน สิ่งที่ผู้เริ่มต้นมักจะกัดคือพวกเขาไม่เข้าใจว่าชื่อไฟล์ที่สัมพันธ์กับไดเรกทอรีทำงานปัจจุบันอย่างไร
tripleee

3
import os

# Set the path
path = 'a\\b\\c'  
# save current working directory
saved_cwd = os.getcwd()
# change your cwd to the directory which contains files
os.chdir(path)
os.rename('a.txt', 'b.klm')
# moving back to the directory you were in 
os.chdir(saved_cwd)

1
ระวังทำอย่างนี้ คุณไม่สามารถchdir()ไปยังไดเรกทอรีได้เสมอเช่นเกิดอะไรขึ้นภายใต้ Windows เมื่อเป็น UNC และการทำchdir()มีผลข้างเคียง ฉันต้องการเพียงระบุเส้นทางที่จำเป็นในการos.rename()โดยตรงไม่มีchdir()ไอเอ็นจี
JonBrave

0

คุณสามารถใช้ os.system เพื่อเรียกใช้งานเทอร์มินัลเพื่อให้งานสำเร็จ:

os.system('mv oldfile newfile')

ใช่สิ่งนี้จะใช้ได้กับเครื่องที่ใช้ระบบปฏิบัติการยูนิกซ์เท่านั้นเนื่องจากmvเป็นโปรแกรม commandline unix ในตัวเพื่อย้าย / เปลี่ยนชื่อไฟล์
Mikhail Geyer

8
ทำไมคุณถึงเรียกใช้เทอร์มินัลและกำหนดคำสั่ง UNIX เท่านั้นเมื่อคุณสามารถทำได้จากหลามในแบบหลายแพลตฟอร์ม?
EndermanAPM

0
import os
import re
from pathlib import Path

for f in os.listdir(training_data_dir2):
  for file in os.listdir( training_data_dir2 + '/' + f):
    oldfile= Path(training_data_dir2 + '/' + f + '/' + file)
    newfile = Path(training_data_dir2 + '/' + f + '/' + file[49:])
    p=oldfile
    p.rename(newfile)

1
ไปข้างหน้าอย่างหนักเข้ารหัสทับเป็นตัวคั่นเส้นทางและการผสมแบบเก่าos.pathกับความทันสมัยpathlibค่อนข้างแน่นอน ไปตลอดทางด้วยpathlibแทน
tripleee

0
import shutil
import os

files = os.listdir("./pics/") 

for key in range(0, len(files)):
   print files[key]
   shutil.move("./pics/" + files[key],"./pics/img" + str(key) + ".jpeg")

สิ่งนี้ควรทำ หลาม 3+


... หรือใช้แจกแจงสำหรับรุ่นที่อ่านได้มากกว่า: สำหรับคีย์, fname ในแจกแจง (ไฟล์): ...
Nicolas D
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.