Tên file tiếng Việt từ Mac sang Windows: không tìm thấy file
Bạn thấy file ngay trong File Explorer. Nhấp đúp vào là mở được bình thường. Nhưng hễ gõ tên file đó vào lệnh, vào script, vào hyperlink trong Excel, vào file batch hay thanh địa chỉ là Windows báo "The system cannot find the file specified" (Hệ thống không tìm thấy tệp được chỉ định). Nếu file có nguồn gốc từ máy Mac và tên file tiếng Việt có dấu, nguyên nhân gần như chắc chắn là chuẩn hóa Unicode: macOS thường lưu tên file ở dạng tổ hợp (NFD), còn mọi thứ bạn gõ trên Windows bằng Unikey hay EVKey đều ở dạng dựng sẵn (NFC). Hai dạng này hiển thị giống hệt nhau trên màn hình nhưng là hai chuỗi ký tự khác nhau, nên Windows coi đó là hai tên khác nhau. Cách sửa là đổi tên file sang dạng dựng sẵn, bằng một lệnh PowerShell ngắn hoặc bằng công cụ chạy trên trình duyệt. Bài này hướng dẫn cả hai cách.
Vì sao tên file tiếng Việt bị lỗi khi chuyển từ Mac sang Windows
Unicode cho phép viết một chữ có dấu theo hai cách. Chữ ệ có thể là một mã ký tự duy nhất (U+1EC7, dạng "dựng sẵn", gọi là NFC), hoặc là chữ e thường đi kèm hai dấu tổ hợp riêng biệt: dấu mũ và dấu nặng (U+0065 + U+0302 + U+0323, dạng "tổ hợp", gọi là NFD). Màn hình vẽ cả hai ra thành ệ. Trình kiểm tra chính tả chấp nhận cả hai. Người đọc không phân biệt được.
Nhưng hệ thống tập tin thì phân biệt. Windows (NTFS) so sánh tên file theo đúng chuỗi ký tự thực tế. Nó bỏ qua khác biệt chữ hoa chữ thường, nhưng không coi ệ và e + ◌̂ + ◌̣ là một. Vì vậy, nếu file Hồ_sơ_Trần_Thị_Mỹ_Lệ.pdf được tạo trên Mac và lưu dưới dạng tổ hợp, rồi bạn gõ Hồ_sơ_Trần_Thị_Mỹ_Lệ.pdf bằng bàn phím Windows, bạn đang hỏi một cái tên không hề tồn tại trên ổ đĩa đó.
macOS từ lâu ưu tiên dạng tổ hợp. Hệ thống tập tin HFS+ cũ chuyển mọi tên file sang NFD, và đến nay nhiều ứng dụng cùng công cụ sao chép trên Mac vẫn tạo ra tên NFD. Khi những file này đi sang Windows qua USB, ổ chia sẻ mạng, thư mục đồng bộ đám mây hay email, cái tên dạng tổ hợp đi theo nguyên vẹn.
Tiếng Việt chịu ảnh hưởng nặng hơn hầu hết các ngôn ngữ khác, vì rất nhiều chữ cái mang cùng lúc hai dấu: ệ, ể, ỗ, ầ, ắ, ặ, ữ, ự. Mỗi chữ như vậy, ở dạng NFD, bị tách thành ba ký tự. Một cái tên như Báo_cáo_tổng_kết_quý_3.xlsx có thể dài hơn tới năm, sáu ký tự so với bản bạn gõ ra, dù trông không khác gì.
Những ký tự bị ảnh hưởng:
- Chữ Việt có dấu và mũ, móc: Nguyễn, Trần, Phạm, Lệ, Hồng, Đặng (riêng chữ Đ là một chữ cái độc lập, không bị tách)
- Chữ Latinh có dấu của các ngôn ngữ khác: José, Zoë, café, Müller
- Chữ Hàn Hangul, bị tách thành từng nét (한글 thành ㅎㅏㄴㄱㅡㄹ ở một số nơi hiển thị)
- Chữ kana tiếng Nhật có dấu dakuten hoặc handakuten (が thành か + ゛)
Tên file thuần ASCII không dấu (bao_cao_quy_3.xlsx) không bao giờ bị ảnh hưởng. Đó là lý do lỗi có vẻ ngẫu nhiên: chỉ file của chị Lệ, anh Hùng hay đối tác dùng Mac mới trục trặc, còn file đặt tên không dấu thì vẫn chạy tốt.
Lưu ý là nhiều người gọi hiện tượng này là "lỗi font chữ". Thực ra không phải. Font hiển thị hoàn toàn đúng; vấn đề nằm ở chuỗi ký tự bên dưới cái tên.
Cách xác nhận đúng là lỗi chuẩn hóa Unicode
Trước khi đổi tên bất cứ thứ gì, hãy chắc chắn thủ phạm là chuẩn hóa Unicode chứ không phải lỗi gõ nhầm, dấu cách thừa ở cuối hay nhầm thư mục. Ba phép thử nhanh:
1. Dùng ký tự đại diện
Mở thư mục chứa file trong PowerShell (nhấp chuột phải vào khoảng trống trong thư mục, chọn Open in Terminal hoặc Open PowerShell window here) rồi chạy:
Get-ChildItem H*.pdf
Nếu dấu sao tìm ra file mà gõ đầy đủ tên lại không ra, nghĩa là tên file chứa ký tự khác với thứ bạn gõ. Đó chính là dấu hiệu của lỗi chuẩn hóa.
2. So sánh độ dài tên
Chạy trong cùng thư mục:
Get-ChildItem | ForEach-Object { "$($_.Name.Length) $($_.Name)" }
Tên Lệ.pdf lẽ ra dài 6 ký tự. Nếu PowerShell báo 8, trong tên có hai ký tự vô hình: dấu mũ và dấu nặng đứng sau chữ e thường.
3. Hỏi thẳng PowerShell
Get-ChildItem | Where-Object { $_.Name -ne $_.Name.Normalize('FormC') } | Select-Object Name
Lệnh này liệt kê mọi file trong thư mục có tên chưa ở dạng dựng sẵn. Nếu file gây lỗi xuất hiện trong danh sách, bạn đã có câu trả lời.
Những chỗ khác trên Windows cũng gặp đúng lệch pha này, dù bạn chưa hề gõ lệnh nào:
- Hyperlink trong Excel hay Word trỏ đến file nội bộ, đồng nghiệp dùng Mac bấm được còn bạn bấm thì báo "Cannot open the specified file".
- Script batch, job sao lưu hoặc công cụ nhập liệu được cấu hình bằng danh sách tên file.
- Hộp thoại "Save As" đề nghị tạo thêm một file
Hồ_sơ_Lệ.pdfthứ hai thay vì hỏi có ghi đè file cũ không. - Hàm VLOOKUP hay XLOOKUP trong Excel không khớp được tên file lấy từ máy Mac với danh sách bạn tự gõ, dù nhìn hai bên giống hệt.
- Tìm kiếm trong một số ứng dụng không ra kết quả với tên đầy đủ, nhưng tìm một phần tên không có chữ có dấu thì lại ra.
Cách 1: đổi tên file trên Windows bằng PowerShell
Nếu bạn quen dùng dòng lệnh, Windows đã có sẵn mọi thứ cần thiết. Hàm Normalize('FormC') của .NET chuyển tên dạng tổ hợp sang dạng dựng sẵn, còn Rename-Item áp dụng tên mới.
-
Mở thư mục bị lỗi trong PowerShell như hướng dẫn ở trên.
-
Xem trước những gì sẽ thay đổi (chưa đổi tên gì cả):
Get-ChildItem -Recurse -File | Where-Object { $_.Name -ne $_.Name.Normalize('FormC') } | Select-Object FullName -
Nếu danh sách đúng ý, tiến hành đổi tên:
Get-ChildItem -Recurse -File | Where-Object { $_.Name -ne $_.Name.Normalize('FormC') } | Rename-Item -NewName { $_.Name.Normalize('FormC') } -
Chạy lại lệnh kiểm tra
-neở phần trước. Giờ nó không nên trả về gì nữa.
Lưu ý và giới hạn:
-Recurseduyệt cả thư mục con. Bỏ nó đi nếu bạn chỉ muốn xử lý thư mục hiện tại. Bản thân tên thư mục cũng có thể ở dạng tổ hợp (ví dụ thư mụcHợp đồng 2024); chạy lệnh thêm một lần nữa không có-Fileđể bắt chúng, đổi tên thư mục sâu nhất trước.- Lệnh này đổi tên trên bản sao của bạn. Nếu file nằm trong thư mục đồng bộ (OneDrive, Dropbox, Google Drive), tên mới sẽ đồng bộ ngược về máy Mac. Thường thì đó là điều bạn muốn, vì tên dạng dựng sẵn chạy được ở cả hai bên.
- Hyperlink hay script nào đã tham chiếu đến tên dạng tổ hợp cũ bằng cách sao chép từ máy Mac sẽ trỏ vào một tên không còn tồn tại. Trên thực tế trường hợp này hiếm, vì toàn bộ vấn đề nằm ở chỗ mọi người gõ ra dạng dựng sẵn.
Cách 2: đổi tên trên trình duyệt, không cần dòng lệnh
Nếu PowerShell không hợp với bạn, hoặc bạn nhận một đống file lẫn lộn cùng file ZIP từ nhiều người gửi, ứng dụng web FilenameFixer miễn phí làm đúng việc chuyển đổi này bằng thao tác kéo thả.
- Mở ứng dụng web trong Chrome, Edge, Firefox hoặc Safari. Giao diện có sẵn tiếng Việt.
- Kéo các file bị lỗi thả vào trang. Có thể thả cả loạt cùng lúc.
- Công cụ nhận diện tên ở dạng tổ hợp và hiển thị phiên bản dựng sẵn (NFC) sẽ được áp dụng.
- Tải các file đã đổi tên về và thay thế bản gốc.
Vài chi tiết đáng biết:
- File và tên file được xử lý ngay trên trình duyệt của bạn, không tải lên máy chủ. Một hợp đồng mật tên
Hợp_đồng_Nguyễn_Văn_Hùng.pdfvẫn nằm yên trên máy bạn. - Nếu tên lỗi nằm bên trong một file ZIP do người dùng Mac gửi, công cụ khôi phục tên trong ZIP sẽ viết lại tên bên trong file nén (tối đa 200 MB) để bạn giải nén bình thường trên Windows, không phải sửa từng file sau khi giải nén.
- Có cả ô dán văn bản. Nếu đồng nghiệp gửi danh sách tên file qua email hay bảng tính mà công thức tra cứu của bạn không khớp được với file trên ổ đĩa, dán danh sách vào rồi sao chép bản đã chuẩn hóa ra.
FilenameFixer không làm được điều gì mà PowerShell không làm được. Nó chỉ bỏ đi việc phải nhớ lệnh nào để chạy, và xử lý được file nén, điều mà cách Rename-Item ở trên không làm được.
Ngăn lỗi tái diễn
Đổi tên chỉ sửa được file của hôm nay. Để tránh đợt sau:
- Nhờ phía dùng Mac gửi qua biểu mẫu web khi có thể. Nhiều đường tải lên qua web chuẩn hóa tên file ngay lúc nhận, dù không phải tất cả.
- Dùng tiện ích Chrome nếu bạn hay tải file làm từ Mac lên các ứng dụng web. Tiện ích FilenameFixer cho Chrome tự động chuyển tên file sang NFC khi bạn chọn file trong hộp thoại tải lên, nên hệ thống quản lý văn bản nội bộ, cổng nộp hồ sơ hay phần mềm quản lý công việc nhận được tên dựng sẵn ngay từ đầu.
- Đặt tên file dùng chung không dấu khi có thể.
hop_dong_nguyen_van_hung.pdfchạy được ở mọi nơi mà không bao giờ dính lỗi này. Nhìn kém đẹp hơn, nhưng với bất cứ thứ gì được script, hyperlink hay danh sách nhập liệu tham chiếu tới, đó là lựa chọn an toàn nhất. - Kiểm tra cài đặt bộ gõ. Unikey và EVKey mặc định xuất ra Unicode dựng sẵn. Nếu ai đó trong nhóm từng chuyển sang "Unicode tổ hợp" để khắc phục một phần mềm cũ nào đó, tên file họ đặt ngay trên Windows cũng sẽ ở dạng NFD.
- Chuẩn hóa trong mã nguồn. Nếu bạn viết phần mềm đọc tên file từ ổ đĩa rồi so sánh với dữ liệu người dùng nhập, hãy chuẩn hóa cả hai bên về NFC trước khi so sánh. Hầu hết ngôn ngữ đều có sẵn một lệnh cho việc này (
.Normalize('FormC')trong .NET,unicodedata.normalize('NFC', s)trong Python,str.normalize('NFC')trong JavaScript).
Đây không phải lỗi của Windows, cũng không phải lỗi của Mac. Cả hai hệ điều hành đều lưu đúng những byte chúng được đưa. Lệch pha chỉ xảy ra vì hai cách viết hợp lệ của cùng một chữ cái gặp nhau trên một ổ đĩa, và cách nhanh nhất để chấm dứt cuộc tranh cãi là chọn dạng dựng sẵn rồi đổi tên.