Thứ Hai, 14 tháng 9, 2026

Đổi tên file hàng loạt bằng Python (Đừng ngồi F2 từng file nếu Python có thể làm thay bạn.)

Cho dù bạn có phải là "dân lập trình" hay không, chỉ cần bàn đã từng "mó" tới máy tính thì trong suốt "cuộc đời mày mò máy tính" nhất định sẽ có một lần bàn phải làm công việc đổi tên từng file một vô cùng nhàm chán và mệt mỏi!

Có một công việc nhìn rất đơn giản:

Đổi tên file.

Một file:

anh1.jpg

Bạn bấm F2.

Đổi thành:

sanpham_01.jpg

Xong.

File thứ hai:

anh2.jpg

F2.

Đổi tên.

File thứ ba...

F2.

File thứ tư...

F2.

...

Đến file thứ 300:

"Ủa... mình đang làm gì với cuộc đời vậy?" 😭

Nếu chỉ có 3–5 file thì làm bằng tay chẳng sao.

Nhưng nếu có:

100 file
500 file
1.000 file

thì đây chính là lúc Python bắt đầu có đất dụng võ.

Hôm nay chúng ta sẽ thử:

Cho Python đổi tên hàng loạt file thay mình.

Và đây cũng là một bước rất đẹp để bắt đầu hiểu Automation.


1. Python có thể đổi tên file thật sao?

Có.

Python không chỉ:

Tính toán
In chữ
Đọc CSV

Nó còn có thể làm việc với file và thư mục trên máy tính.

Ví dụ:

old_name.txt

có thể đổi thành:

new_name.txt

Hoặc:

anh1.jpg
anh2.jpg
anh3.jpg
...
anh100.jpg

thành:

sanpham_001.jpg
sanpham_002.jpg
sanpham_003.jpg
...
sanpham_100.jpg

Một chương trình.

Một lần chạy.

Cả đống file được xử lý.

Đây mới bắt đầu có mùi:

Automation. 😎


2. Module os là gì?

Python có module:

os

os cung cấp nhiều công cụ để làm việc với hệ điều hành.

Ví dụ:

  • xem thư mục
  • tạo thư mục
  • kiểm tra file
  • đổi tên file
  • xóa file
  • làm việc với đường dẫn

Chúng ta có thể bắt đầu bằng:

import os

Sau đó dùng:

os.rename()

để đổi tên file.


3. Đổi tên một file đầu tiên

Giả sử thư mục có:

old.txt

Bạn muốn đổi thành:

new.txt

Code:

import os

os.rename("old.txt", "new.txt")

Chạy chương trình.

File:

old.txt

biến thành:

new.txt

😎

Không cần:

  • click chuột
  • F2
  • gõ tên
  • Enter

Python làm.


4. os.rename() thực sự đang làm gì?

Câu lệnh:

os.rename("old.txt", "new.txt")

có thể hiểu đơn giản:

"Hệ điều hành ơi, đổi tên file old.txt thành new.txt giúp tôi."

Trong đó:

old.txt

là tên cũ.

new.txt

là tên mới.


5. Đổi tên file trong thư mục khác

Giả sử cấu trúc:

my_project/
│
├── main.py
│
└── files/
    └── old.txt

Bạn có thể viết:

import os

os.rename("files/old.txt", "files/new.txt")

Python sẽ đổi:

files/old.txt

thành:

files/new.txt

Điểm quan trọng ở đây:

Đường dẫn file phải đúng.

Đây là chỗ người mới rất dễ gặp lỗi.


6. Lỗi kinh điển: FileNotFoundError 😭

Bạn viết:

os.rename("old.txt", "new.txt")

Nhưng Python báo:

FileNotFoundError

Bạn:

"Ủa file có ở đó mà?"

Python:

"Tôi không thấy."

Bạn:

"Nó nằm ngay trước mặt tôi!"

Python:

"Nhưng không nằm ở chỗ tôi đang tìm."

😂

Đây là điểm rất quan trọng:

File Explorer đang mở ở đâu không có nghĩa Python đang tìm file ở đó.

Python làm việc dựa trên đường dẫn và thư mục hiện tại của chương trình.


7. Kiểm tra Python đang đứng ở đâu

Bạn có thể dùng:

import os

print(os.getcwd())

getcwd() là:

Get Current Working Directory

Nói đơn giản:

"Python ơi, hiện tại ông đang đứng ở thư mục nào?"

Ví dụ:

C:\Users\An\Projects\my_project

Nếu bạn có:

C:\Users\An\Projects\my_project\files\old.txt

thì:

os.rename("files/old.txt", "files/new.txt")

mới hợp lý.


8. Kiểm tra file có tồn tại không

Trước khi đổi tên, bạn có thể kiểm tra:

import os

if os.path.exists("old.txt"):
    os.rename("old.txt", "new.txt")
else:
    print("Không tìm thấy file!")

Cách này giúp chương trình không lao đầu vào tường ngay lập tức. 😆

Nếu file tồn tại:

old.txt

→ đổi tên.

Nếu không:

Không tìm thấy file!

9. Nhưng đổi một file thì chưa có gì ghê gớm

Đúng.

Nếu bạn chỉ cần đổi:

old.txt

thành:

new.txt

thì bấm F2 còn nhanh hơn viết Python. 😂

Vậy sức mạnh nằm ở đâu?

Ở đây:

Đổi hàng loạt.


10. Đổi tên 10 file bằng Python

Giả sử thư mục:

photos/
│
├── img1.jpg
├── img2.jpg
├── img3.jpg
├── img4.jpg
└── img5.jpg

Bạn muốn thành:

product_01.jpg
product_02.jpg
product_03.jpg
product_04.jpg
product_05.jpg

Python có thể dùng vòng lặp:

import os

for i in range(1, 6):
    old_name = f"img{i}.jpg"
    new_name = f"product_{i:02d}.jpg"

    os.rename(old_name, new_name)

Kết quả:

img1.jpg → product_01.jpg
img2.jpg → product_02.jpg
img3.jpg → product_03.jpg
img4.jpg → product_04.jpg
img5.jpg → product_05.jpg

Một vòng for.

Năm file.

Nếu có 500 file thì sao?

Thay đổi:

range(1, 6)

thành:

range(1, 501)

😎


11. f"..." là gì?

Bạn thấy:

old_name = f"img{i}.jpg"

Đây là f-string.

Nó cho phép đưa biến vào trong chuỗi.

Nếu:

i = 3

thì:

f"img{i}.jpg"

trở thành:

img3.jpg

Tương tự:

f"product_{i}.jpg"

với:

i = 3

sẽ thành:

product_3.jpg

12. Còn {i:02d} là gì?

Đây là một chi tiết rất hữu ích khi đặt tên file.

f"product_{i:02d}.jpg"

02d có thể hiểu đơn giản:

"Số nguyên, tối thiểu 2 chữ số. Thiếu thì thêm số 0 phía trước."

Ví dụ:

1  → 01
2  → 02
9  → 09
10 → 10

Vì vậy:

product_01.jpg
product_02.jpg
...
product_09.jpg
product_10.jpg

Nhìn gọn hơn rất nhiều.


13. Tại sao không đặt product_1.jpg, product_2.jpg?

Bạn hoàn toàn có thể.

Nhưng khi số lượng file lớn, cách đánh số cố định giúp việc sắp xếp dễ hơn.

Ví dụ:

product_1.jpg
product_2.jpg
product_10.jpg

Một số cách sắp xếp có thể khiến thứ tự nhìn không như bạn mong muốn.

Trong khi:

product_01.jpg
product_02.jpg
product_10.jpg

thì nhìn rất rõ.

Với 100 file, bạn có thể dùng:

f"product_{i:03d}.jpg"

để có:

001
002
003
...
100

14. Nhưng thực tế file thường không đẹp như vậy 😭

Đây mới là chuyện đời.

Bạn không có:

img1.jpg
img2.jpg
img3.jpg

mà có:

IMG_8237.jpg
DSC_00482.jpg
photo-final.jpg
new.jpg
new-final.jpg
new-final-2.jpg
abc123.jpg

😂

Lúc này không thể chỉ dùng:

for i in range(...)

rồi đoán tên file.

Chúng ta cần:

Đọc danh sách file thực tế trong thư mục.


15. Lấy danh sách file bằng os.listdir()

Python có:

os.listdir()

Ví dụ:

import os

files = os.listdir("photos")

print(files)

Nếu thư mục có:

IMG_8237.jpg
DSC_00482.jpg
photo-final.jpg

có thể nhận được:

['IMG_8237.jpg', 'DSC_00482.jpg', 'photo-final.jpg']

Python vừa:

"Đi vào thư mục."

và:

"Xem bên trong có gì."


16. Đổi tên toàn bộ file trong thư mục

Ví dụ:

import os

folder = "photos"

files = os.listdir(folder)

for i, filename in enumerate(files, start=1):
    old_path = os.path.join(folder, filename)
    new_name = f"photo_{i:03d}.jpg"
    new_path = os.path.join(folder, new_name)

    os.rename(old_path, new_path)

Ý tưởng:

Lấy danh sách file
       ↓
Duyệt từng file
       ↓
Tạo tên mới
       ↓
Đổi tên

Ví dụ:

IMG_8237.jpg       → photo_001.jpg
DSC_00482.jpg      → photo_002.jpg
photo-final.jpg    → photo_003.jpg

Đây mới thực sự là:

Đổi tên hàng loạt.


17. enumerate() là gì?

Đoạn:

for i, filename in enumerate(files, start=1):

có nghĩa đơn giản:

"Duyệt qua từng file và đồng thời đánh số cho nó."

Ví dụ:

file A → 1
file B → 2
file C → 3

Nếu:

start=1

thì bắt đầu từ 1.

Nếu không ghi, enumerate() mặc định bắt đầu từ 0.


18. os.path.join() rất đáng nhớ

Bạn có:

folder = "photos"

và:

filename = "IMG_8237.jpg"

Bạn có thể nối chúng bằng:

os.path.join(folder, filename)

Kết quả sẽ tạo đường dẫn phù hợp với hệ điều hành.

Ví dụ:

photos/IMG_8237.jpg

Điều này tốt hơn việc tự ghép chuỗi bằng tay:

folder + "/" + filename

vì Windows và macOS/Linux có cách biểu diễn đường dẫn khác nhau.


19. Khoan! Đừng chạy ngay code đổi tên hàng loạt 😱

Đây là một bài học cực kỳ quan trọng.

Khi code chỉ:

print(filename)

thì sai cũng chẳng sao.

Nhưng:

os.rename(...)

thao tác thật lên file.

Nếu code sai:

ảnh A → tên mới
ảnh B → tên mới
ảnh C → tên mới
...

Bạn có thể tạo ra một mớ hỗn độn.

Vì vậy, khi viết automation:

Test bằng print() trước.


20. Cách an toàn hơn: In ra trước khi đổi

Thay vì:

os.rename(old_path, new_path)

hãy thử:

print(old_path, "→", new_path)

Ví dụ:

import os

folder = "photos"

files = os.listdir(folder)

for i, filename in enumerate(files, start=1):
    old_path = os.path.join(folder, filename)
    new_name = f"photo_{i:03d}.jpg"
    new_path = os.path.join(folder, new_name)

    print(old_path, "→", new_path)

Kết quả:

photos/IMG_8237.jpg → photos/photo_001.jpg
photos/DSC_00482.jpg → photos/photo_002.jpg
photos/photo-final.jpg → photos/photo_003.jpg

Bạn nhìn.

Kiểm tra.

Thấy đúng.

Sau đó mới bật os.rename().

Đây là tư duy debug cực kỳ quan trọng.


21. Chỉ đổi tên file .jpg

Bạn không muốn Python đổi cả:

README.txt
data.csv
main.py

Bạn chỉ muốn xử lý:

.jpg

Có thể kiểm tra:

if filename.lower().endswith(".jpg"):

Ví dụ:

import os

folder = "photos"

files = os.listdir(folder)

for i, filename in enumerate(files, start=1):
    if filename.lower().endswith(".jpg"):
        print(filename)

Python chỉ xử lý file JPG.


22. Giữ nguyên phần mở rộng của file

Đây là lỗi người mới rất dễ mắc.

Giả sử thư mục có:

photo1.jpg
photo2.png
photo3.jpeg

Nếu bạn viết:

new_name = f"image_{i}.jpg"

thì bạn đang ép tất cả thành .jpg.

Không tốt.

Nếu muốn giữ extension cũ, có thể dùng:

name, ext = os.path.splitext(filename)

Ví dụ:

photo1.jpg

sẽ tách thành:

name = photo1
ext = .jpg

Sau đó:

new_name = f"image_{i:03d}{ext}"

Kết quả:

photo1.jpg → image_001.jpg
photo2.png → image_002.png
photo3.jpeg → image_003.jpeg

23. Một chương trình thực tế hơn

Đây là phiên bản khá dễ hiểu để thử:

import os

folder = "photos"

files = os.listdir(folder)

count = 1

for filename in files:
    old_path = os.path.join(folder, filename)

    if os.path.isfile(old_path):
        name, ext = os.path.splitext(filename)

        new_name = f"image_{count:03d}{ext}"
        new_path = os.path.join(folder, new_name)

        print(filename, "→", new_name)

        count += 1

Chú ý:

Ở phiên bản này chúng ta chưa gọi os.rename().

Chỉ:

print(...)

để kiểm tra.

Sau khi chắc chắn:

print(filename, "→", new_name)

đúng rồi, mới thay bằng:

os.rename(old_path, new_path)

24. Nhưng có một cái bẫy lớn: tên mới có thể trùng 😱

Giả sử thư mục đã có:

image_001.jpg

Bạn chạy script và Python muốn đổi một file khác thành:

image_001.jpg

Đây có thể gây lỗi hoặc tạo hành vi không như bạn mong muốn tùy hệ điều hành và tình huống.

Vì vậy:

Automation liên quan tới file luôn phải nghĩ tới chuyện tên mới đã tồn tại chưa.

Có thể kiểm tra:

if os.path.exists(new_path):
    print("Tên file đã tồn tại:", new_path)
else:
    os.rename(old_path, new_path)

25. Một nguyên tắc rất đáng nhớ: Đừng "tin" dữ liệu đầu vào

File trong thư mục có thể:

  • tên rất lạ
  • có khoảng trắng
  • có ký tự đặc biệt
  • có extension viết hoa
  • đã tồn tại tên mới
  • không phải file mà là thư mục

Cho nên automation tốt không phải:

"Code chạy được là xong."

Mà là:

Code chạy được + kiểm tra các tình huống có thể xảy ra.

Đây chính là khác biệt giữa:

"Viết được Python."

và:

"Bắt đầu biết làm project thực tế."


26. pathlib – cách hiện đại hơn

Ngoài os, Python còn có:

pathlib

Ví dụ:

from pathlib import Path

file = Path("old.txt")

file.rename("new.txt")

Cách này khá dễ đọc.

Làm việc với thư mục:

from pathlib import Path

folder = Path("photos")

for file in folder.iterdir():
    print(file)

pathlib rất đáng học khi làm việc với file và thư mục.

Nhưng với người mới, hiểu:

os.rename()
os.listdir()
os.path.join()

trước cũng hoàn toàn ổn.

Không cần học cả hai cùng lúc rồi tự làm mình rối. 😄


27. Python đang bắt đầu "làm việc" thay bạn

Hãy nhìn lại.

Bài #69:

CSV
↓
Đọc dữ liệu

Bài #70:

Files
↓
Đọc danh sách file
↓
Đổi tên

Đây là một bước chuyển quan trọng.

Python không còn chỉ:

print("Hello World")

nữa.

Nó bắt đầu:

Nhìn vào thư mục
↓
Tìm file
↓
Kiểm tra file
↓
Đổi tên file

Bạn đang bắt đầu dùng Python như một công cụ tự động hóa.


28. Ví dụ thực tế: Đổi tên tài liệu

Giả sử thư mục có:

document1.pdf
document2.pdf
document3.pdf
...
document100.pdf

Bạn muốn:

invoice_001.pdf
invoice_002.pdf
invoice_003.pdf
...
invoice_100.pdf

Thay vì:

F2
gõ
Enter
F2
gõ
Enter
...

Python có thể xử lý.

Đây chính là kiểu công việc mà automation sinh ra để làm.


29. Ví dụ thực tế: Đổi tên file tải về

Bạn thường xuyên tải file về và nhận:

download
download (1)
download (2)
download (3)
download (4)

😭

Sau đó bạn muốn:

report_001.pdf
report_002.pdf
report_003.pdf
report_004.pdf

Nếu có 5 file:

Làm tay được.

Nếu có 500 file:

Python, tới lượt mày. 😎


30. Một điều rất quan trọng: Backup trước khi chạy

Đây là lời khuyên nghiêm túc nhất bài.

Nếu bạn thử script đổi tên file lần đầu:

Hãy thử trên một thư mục test.

Ví dụ:

test_rename/
├── a.txt
├── b.txt
├── c.txt

Đừng lần đầu tiên thử ngay trên:

Ảnh gia đình 15 năm

hoặc:

Project công ty

😂

Automation rất mạnh.

Nhưng:

Mạnh thì cũng có thể mạnh tay.

Hãy test trước.


31. Debug theo kiểu "chậm mà chắc"

Khi làm script đổi tên file, hãy đi theo thứ tự:

Bước 1
↓
Đọc thư mục
print(os.listdir(folder))

Bước 2
↓
Chỉ lọc file cần xử lý
if filename.lower().endswith(".jpg"):

Bước 3
↓
In tên cũ → tên mới
print(old_name, "→", new_name)

Bước 4
↓
Kiểm tra tên mới có trùng không

Bước 5
↓
Cuối cùng mới os.rename()

Đừng viết một lèo 50 dòng rồi:

"Chạy thử xem sao."

Đến lúc 500 file bị đổi sai:

"Thôi xong." 😭


32. Chua thêm 😆: F2 là một hình thức "automation thủ công"

Bạn có 5 file.

Bạn:

F2 → gõ → Enter
F2 → gõ → Enter
F2 → gõ → Enter
F2 → gõ → Enter
F2 → gõ → Enter

Bạn gọi đó là:

"Tôi đang làm việc."

Bạn có 1.000 file.

Bạn vẫn:

F2 → gõ → Enter
F2 → gõ → Enter
...

Sau 2 tiếng:

"Tại sao mình học Python vậy?" 😭

Đây chính là câu hỏi rất đúng.

Bạn học Python để những việc như vậy có thể trở thành:

python rename_files.py

Rồi ngồi uống cà phê. ☕😎


33. Chua thêm lần 2 😂: Python không cần nghỉ giải lao

Bạn:

"Đổi 500 file chắc mất cả buổi."

Python:

"500 thôi hả?"

Bạn:

"Ừ."

Python:

"Chạy đi."

Bạn:

"..."

Python:

"Xong."

😂

Nhưng nhớ:

Python làm nhanh không có nghĩa Python luôn làm đúng.

Đây là lý do bài này liên tục nhắc:

Test → Print → Kiểm tra → Rồi mới Rename.


34. Checklist – Bạn đã sẵn sàng cho Automation chưa? ✅

File cơ bản

  • Biết os là gì

  • Biết os.rename()

  • Biết os.listdir()

  • Biết os.path.join()

  • Biết os.path.exists()

  • Biết os.path.isfile()

  • Biết os.path.splitext()

Python

  • Biết dùng vòng for

  • Biết enumerate()

  • Biết f-string

  • Hiểu {i:02d}

  • Biết {i:03d}

Debug

  • Biết kiểm tra thư mục hiện tại

  • Biết xử lý FileNotFoundError

  • Biết kiểm tra file tồn tại

  • Biết kiểm tra tên mới bị trùng

  • Biết test bằng print() trước khi thay đổi file thật

An toàn

  • Test trên thư mục riêng

  • Backup dữ liệu quan trọng

  • Không chạy script "mù" trên thư mục thật

  • Kiểm tra kết quả trước khi xử lý hàng loạt


35. FAQ nhanh

❓ Python có thể đổi tên file thật không?

Có.

Ví dụ:

os.rename("old.txt", "new.txt")

❓ Có cần cài package không?

Không.

os là module có sẵn trong Python.


❓ Python có đổi được hàng trăm file không?

Có.

Đó chính là một trong những trường hợp automation rất hữu ích.


❓ Nếu đổi tên sai thì sao?

Có thể rất phiền.

Vì vậy:

Luôn test trên thư mục mẫu trước.

Đặc biệt với dữ liệu quan trọng.


os hay pathlib tốt hơn?

Cả hai đều hữu ích.

pathlib là cách hiện đại và thường dễ đọc khi làm việc với đường dẫn.

Nhưng os rất phù hợp để người mới hiểu những thao tác cơ bản.


❓ Có thể đổi cả phần mở rộng không?

Có.

Nhưng phải cực kỳ cẩn thận.

Đổi:

file.txt

thành:

file.jpg

không biến nội dung file text thành hình ảnh.

Đổi tên extension không đồng nghĩa với chuyển đổi định dạng file.

Đây là hai chuyện hoàn toàn khác nhau.


36. Tóm lại

Hôm nay chúng ta không học một thứ gì quá "cao siêu".

Chúng ta chỉ làm:

Đổi tên file.

Nhưng phía sau nó là rất nhiều tư duy quan trọng:

Python
 ↓
Làm việc với hệ điều hành
 ↓
Đọc thư mục
 ↓
Tìm file
 ↓
Kiểm tra
 ↓
Xử lý
 ↓
Thay đổi hàng loạt

Bạn đã đi từ:

print("Hello")

đến:

os.rename(...)

Nghe nhỏ thôi.

Nhưng đây là một bước rất quan trọng.

Bởi vì lập trình thực tế không phải lúc nào cũng là:

"Viết một thuật toán thật hoành tráng."

Rất nhiều khi nó chỉ là:

Có một công việc nhàm chán phải làm 500 lần → viết code để máy làm.

Và đó chính là:

Automation. 🤖