如何翻譯大型 TXT 檔案:編碼、章節與換行
在翻譯長篇 .txt 檔案之前,先修正編碼、標記章節,並解除硬換行。內含範例檔案、免費檢查工具,以及 9 次測試。

若要翻譯大型 TXT 檔案,請在上傳到任何地方之前先準備好三件事。第一,確認文字以正確的編碼解碼,並存成 UTF-8。第二,讓每個章節標題各自獨立成行,且前後各留一個空行。第三,如果檔案以固定寬度斷行,請將這些行接起來,讓每個段落成為一行,段落之間以空行分隔。接著翻譯整個檔案,事後再比對原文與譯文的段落數和章節數。
純文字檔案沒有樣式、沒有標題,也沒有中繼資料。翻譯工具對其結構的所有認知,都來自位元組與換行。這就是為什麼同樣的三個問題反覆出現:位元組以錯誤的編碼讀取、章節無法與一般行區分,或是換行完全無法說明句子在哪裡結束。
我們製作了四種編碼的範例檔案、寫了一個免費檢查工具,並用本機模型將一篇硬換行的短篇故事翻譯成簡體中文九次。當模型看到完整檔案時,它能妥善處理硬換行。但在三次依行數切分檔案的執行中,模型全都弄斷了句子,還把某個角色的動作歸給了另一個角色。
快速檢查清單
| 檢查項目 | 理想狀態 | 修正方式 |
|---|---|---|
| 編碼 | 開頭幾行讀取正確;檔案為 UTF-8 | 以正確的編碼重新開啟,再存成 UTF-8 |
| 位元組順序標記 | 沒有,或是你知道存在的標記 | 若有工具抱怨,請存成「UTF-8」而非「UTF-8 with BOM」 |
| 章節標題 | 每個標題獨立成行,前後各有一個空行 | 修正少數與正文連在一起的標題 |
| 段落 | 段落之間有一個空行 | 在僅以縮排開頭的段落之間補上空行 |
| 硬換行 | 每個段落是一長行 | 接合段落內的行,但詩句、書信和清單保持原樣 |
| 換行符號 | 全文統一使用一種格式 | 轉換舊式 Mac 的 CR 換行;LF 和 CRLF 都沒問題 |
| 文字損毀 | 沒有 � 字元 | 取得更好的副本。轉換無法讓遺失的字元復原 |
檢查工具會逐列回報,並修正編碼、位元組順序標記、換行符號和強制換行。章節標題和缺少的空行則需要你手動修正。執行 python3 check_txt.py inspect yourfile.txt 可查看報告,執行 python3 check_txt.py convert yourfile.txt clean.txt --unwrap 可寫出已合併段落的 UTF-8 副本。它只需要 Python 3,而且絕不會變更原始檔案。
步驟 1:確認正確的編碼
TXT 檔案是一連串的位元組。編碼是將這些位元組轉換為字元的規則,而檔案本身並不會說明使用了哪條規則。如果程式猜錯了,就會出現亂碼:文字變得混亂,或者更糟,文字看起來沒問題,但卻不是原本寫的內容。
以下是同一個中文詞句「最后一班渡轮」(「the last ferry」),以錯誤的規則讀取。我們用 Python 內建的編解碼器產生了這些結果,你也可以用範例檔案重現。
| 儲存為 | 讀取為 | 你看到的內容 |
|---|---|---|
| GB18030 | Windows-1252 | ×îºóÒ»°à¶ÉÂÖ |
| GB18030 | UTF-8 | ���һ����� |
| UTF-8 | GBK | 鏈�鍚庝竴鐝�娓¤疆 |
| Shift_JIS(日文 最後のフェリー) | GBK | 嵟屻偺僼僃儕乕 |
最後一列是最危險的。日文位元組以中文讀取會產生真正的中文字元,不會出現錯誤,也沒有 �。翻譯工具會很樂意翻譯它們,而結果將是文法正確的胡言亂語。
我們的檢查工具說明了為什麼你不能依賴「它開啟時沒有錯誤」。當我們對 Shift_JIS 範例執行檢查時,有兩種編碼在解碼整個檔案時完全沒有錯誤:
encoding: unknown (not UTF-8)
these legacy encodings decode without errors; read the previews,
because a wrong one can still produce real-looking characters:
gb18030 戞堦榖丂嵟屻偺僼僃儕乕
cp932 第一話 最後のフェリー
只有第二行是日文。第一行是一串沒有人寫過的罕見中文字元。在 GB18030 中文範例上,有五種編碼在解碼時沒有錯誤,而其中只有一種,也就是 GB18030,顯示出章節標題「第一章 最后一班渡轮」。所以規則很簡單:根據閱讀前幾行來決定編碼,而不是根據程式有沒有報錯。
猜測通常會出錯的地方:
- 來自舊版 Windows 系統或中文網站的的中文文字通常是 GBK 或 GB18030。GB18030 涵蓋了 GBK 的所有內容,而瀏覽器所遵循的 WHATWG 編碼標準 更進一步指出:「GBK 的解碼器就是 gb18030 的解碼器。」如果檔案是 GBK,以 GB18030 開啟即可。
- 來自台灣或香港的繁體中文通常是 Big5。
- 日文通常是 Shift_JIS,或微軟的擴充版本,Windows 和 Python 稱之為 cp932。
- 韓文通常是 EUC-KR。
- 充滿 NUL 位元組的檔案,或每隔一個字元看起來像空白的檔案,通常是沒有位元組順序標記的 UTF-16。
位元組順序標記(BOM)是檔案開頭的一段簡短隱形代碼,用以宣告 UTF-8、UTF-16 或 UTF-32。若有 BOM,請信任它。同一標準指出:「位元組順序標記比其他任何東西都更具權威性。」我們的檢查工具會先讀取 BOM,只有在沒有 BOM 時才進行猜測。
將檔案儲存為 UTF-8
一旦文字讀取正確,就將其儲存為 UTF-8。WHATWG 標準稱 UTF-8 為「最適合 Unicode 交換的編碼」,而且對任何翻譯工具來說都是最安全的選擇。
還有一個對翻譯特別重要的第二個原因。舊版編碼只涵蓋其所在地區的字元。Shift_JIS 沒有「这」的編碼,也就是「这是最后一班渡轮」的第一個字,Big5 也沒有,因為它是簡體中文字。Windows-1252 無法儲存西里爾字母。如果翻譯後的檔案必須以原始的舊版編碼寫回,目標語言可能無法容納。BookTranslator 的 TXT 翻譯工具 表示它會自動偵測常見編碼,並傳回「與輸入相同編碼」的翻譯檔案,因此從 UTF-8 開始就完全消除了這個問題。
您可以在文字編輯器中轉換(以正確的編碼開啟,然後「另存為」UTF-8),在 macOS 或 Linux 上使用 iconv -f GB18030 -t UTF-8 in.txt > out.txt,或使用檢查工具:
python3 check_txt.py convert book.txt book-utf8.txt --encoding gb18030
如果檔案已經包含 � 字元,損壞在您取得之前就已發生。再次轉換不會還原遺失的字元。請尋找更好的來源副本。
步驟 2:讓章節易於尋找
章節很重要,原因有三。長檔案會分段翻譯,而章節分隔是最乾淨的切割點。翻譯後您會想檢查每一章。而且如果您之後將文字轉換為電子書,章節標題會成為目錄。
將每個標題放在獨立的一行,前後各留一個空行,並在全書中使用同一種模式。以下是我們的檢查工具會計數的模式:
Chapter 1,Chapter One: The Last Ferry,Part Two,Prologue,Epilogue第一章,第12回,第三話,第二卷- 一行中單獨出現的數字或羅馬數字,例如
12或XII.
執行 inspect 並閱讀它找到的標題清單。如果這本書有 40 章,而檢查工具找到 37 章,那麼有三個標題隱藏了:一個與第一句連在一起,一個使用了不同的詞如「Ch. 7」,或一個在同一行上有文字。手動修正這三個。這比在翻譯後的檔案中尋找問題所花的時間更少。
步驟 3:小心地取消硬換行
有些 TXT 檔案會以固定寬度斷行,以便文字能放入純文字終端機或窄視窗。從 PDF 複製的文字和 OCR 輸出也會在印刷頁面的寬度處做同樣的事。在這些檔案中,換行代表「該行已滿」,而不是「句子或段落結束」。
硬換行很容易辨認。在我們的硬換行範例中,檢查工具回報:
non-empty lines: 43; longest line: 66 chars; 25 lines within 12 chars of the longest
line breaks inside paragraphs that do not end a sentence: 23
looks hard-wrapped: consider convert --unwrap
修正方法是將每個段落內的行連接起來,並保留段落之間的空行。陷阱在於換行是真實的文字:詩歌、歌詞、信件、地址、食譜和清單。我們的範例包含一封五行信件:
My dear Mara,
The key is under the blue pot.
Do not let your uncle sell the boat.
With love, always,
Nonna
粗暴地「將每個單一換行替換為空格」會把它變成一行連續文字。檢查工具的 --unwrap 只在段落中大多數行都接近全寬時才連接該段落,因此像這封信這樣的短行區塊會被保留不動。在我們的範例上,它精確地重建了原始未換行的檔案,逐位元組完全一致,包括信件。在您自己的檔案上,請先檢查幾個連接後的段落和每個詩歌區塊,再信任它。
還有兩個細節。當您連接中文或日文文字的行時,不要在它們之間加入空格;檢查工具連接 CJK 行時不會加入空格,包括以 CJK 標點結尾的行。如果您的文字來自 OCR,單詞也可能在行尾以連字號分割,這需要各自的決定。我們的 修復 OCR 換行和連字號指南 涵蓋了這一點。
我們測試了什麼:硬換行文字,完整與切割的比較
我們想知道硬換行是否真的會損害翻譯,還是只是看起來不整齊。我們為測試寫了一篇 396 字的短篇故事:三個章節、十五個段落、對話、上面的信件,以及一個 * * * 場景分隔符。我們用相同的文字存了兩次:未換行,每段一行;以及在 66 個字元處硬換行,後者有 43 個非空行,而非 19 個。
接著我們請一個本地模型用三種方式將它翻譯成簡體中文,每種方式各跑三次:
- 已換行,整個檔案。 將硬換行的檔案在一次請求中送出。
- 未換行,整個檔案。 將未換行的檔案在一次請求中送出。
- 已換行,每 12 行切分。 將硬換行的檔案每 12 行切分,每段一次請求,再將回覆拼接回去。這就是腳本或工具按行數而非按段落切分長檔案時會發生的情況。
模型是 LM Studio 中的 Qwen 3.6 27B (Q4_K_M),關閉思考功能,temperature 設為 0.3,運行於配備 64 GB 記憶體的 Apple M4 Max 上。每次請求都使用相同的一句話提示。我們在 2026 年 10 月 28 日執行。腳本為 run_llm_txt_test.py,全部九個輸出均未經編輯發布,而 results.csv 每次運行各有一行記錄。
| 已換行,整個檔案 | 未換行,整個檔案 | 已換行,每 12 行切分 | |
|---|---|---|---|
| 保留的段落 (15) | 3 次運行中 3 次 | 3 次運行中 3 次 | 3 次中 0 次(每次 14 段) |
| 保留的章節標題 (3) | 3 次中 3 次 | 3 次中 3 次 | 3 次中 3 次 |
| 信件保留為五行 | 3 次中 3 次 | 3 次中 3 次 | 3 次中 3 次 |
| 在切分點被截斷的句子 | 0 | 0 | 每次運行 3 句 |
| 動作被歸給錯誤的角色 | 0 | 0 | 3 次執行中的 3 次 |
第一個發現讓我們很意外。當模型看到整個硬換行的檔案時,它自己把各行接了回去。三次輸出都是一段一行,與未換行的執行結果同樣是 19 行,讀起來也一樣順暢。所以單就這個短檔案而言,硬換行本身並沒有對這個模型造成傷害。
按行數切分檔案確實造成了傷害,而且每次都在同樣的地方出錯。12 行片段中有三段在句子中間結束。第一段結束於「He pointed with his」,下一段則以「pen at a three-storey building on the corner.」開頭。分開翻譯後,後半段失去了主語。有兩次執行把它譯成「她瞥了一眼街角那棟三層樓的建築」,第三次則以「隨後她重新回到填字遊戲上」結尾。在故事裡,售票亭裡的男人指了一下,然後回去做他的填字遊戲。但在三次執行中,讀中文的人都會以為是瑪拉做的。
第二個切點位於「the careful, slightly old-fashioned hand she had learned at a」和「convent school,」之間,讓中文句子在三次執行中都懸在「那是她在」——有一次執行還多了一個「一」——而「learned」這個詞消失了。第三個切點把關於百葉窗的句子拆成兩行,後半段把「painted, not well, but not long ago」變成了油漆剝落:兩次執行譯成「油漆雖已斑駁」,第三次譯成「油漆剝落」。而且因為各片段只用單一換行連接,場景轉換前的空行消失了,這就是為什麼每次執行都只有 14 段而不是 15 段。我們的檢查程式抓到了段落數。它抓不到角色錯誤;那是我們靠閱讀發現的。
這對你的檔案意味著什麼:
- 取消換行能保護你不受無法控制的切分器影響。 每個長檔案都會在某處被切分,無論是你自己的腳本、聊天視窗的限制,還是你上傳所用的工具。如果段落是單行並以空行分隔,任何合理的切分器都能在段落之間切分,而不是在句子內部切分。
- 最嚴重的錯誤讀起來很流暢。「她瞥了一眼那棟建築」是通順的中文。讀者會注意到每個切點處奇怪的換行,以及懸空的「那是她在」,但沒有任何標記把角色錯誤或油漆剝落標示為錯誤。切分點上的錯誤首先是意義錯誤,其次才是格式錯誤。
- 這只是一個模型和一篇短篇故事。 這麼短的檔案能放進單一請求,所以整檔執行從來不需要切分任何東西。整本小說確實必須切分,而這正是步驟 1 到 3 的準備工作發揮作用的時候。這些檔案測試的是準備與切分,而不是 BookTranslator 自己的流程。
一個較小的觀察:在六次整檔執行中,模型有五次把瑪拉的名字寫成「瑪拉」,一次寫成「馬拉」。每份輸出本身都一致,但不同的請求彼此並不一致。對於分成許多片段翻譯的長篇書籍,一份名字及其約定拼法的清單能讓每一章保持一致。我們的術語表指南說明了如何建立一份。
步驟 4:翻譯,然後檢查計數
檔案乾淨之後,翻譯就是輕鬆的部分了。你可以把它上傳到 BookTranslator 的 TXT 翻譯工具,它接受 .txt、.md 和 .mdx 檔案,宣稱可處理最大 300 MB 的 TXT 檔案,並在結帳前顯示價格。沒有免費的完整翻譯,但上傳本身就會告訴你費用。如果你偏好使用聊天模型或本機 LLM,請自行在章節或段落邊界切分檔案,並為名字保留一份術語表。如果你的文字是 Markdown 而非純散文,請參閱我們的 Markdown 翻譯指南,因為 Markdown 語法有其自己的規則。
翻譯之後,比較這兩個檔案:
python3 check_txt.py compare book-utf8.txt book-translated.txt
如果任一檔案不是 UTF-8,請加上 --source-encoding 或 --translated-encoding。章節檢查認得英文和中文/日文的標題模式;對於其他目標語言,請把該語言中「chapter」的對應詞加到腳本頂端的模式中。
這是我們其中一次切分執行的報告:
source translated
paragraphs 15 14 <- differs
chapter headings 3 3
non-empty lines 43 24 <- differs
scene breaks (* * *) 1 1
replacement chars 0 0
source script LATIN characters left in translation: 0
這樣讀它:
- 段落和章節標題應該相符。缺少段落通常意味著兩段被合併或有一段被丟棄。
- 非空行數可能因為正當理由而不同。我們的整檔換行執行從 43 行變成 19 行,因為模型把硬換行的各行接了回去,這是一項改善。只有在來源本來就未換行時,才比較行數。
- 殘留的來源文字字元指向完全沒有翻譯的段落。少數幾個對名字、產品術語或引文來說是正常的;連續出現一大串則表示有段落被跳過。
- 譯文中的替換字元表示輸出過程中發生了編碼問題。
計數無法告訴你翻譯是否正確。請閱讀每一章的第一段和最後一段,以及檔案每個切分點前後的段落。我們的測試就是在這些地方發現了每一個嚴重錯誤。
常見問題
為什麼我的 TXT 檔案在一個程式裡看起來正常,在另一個程式裡卻是亂碼?
這兩個程式猜測了不同的編碼。其中一個猜對了。找出能正確顯示文字的編碼,然後把檔案存成 UTF-8,讓每個程式都以相同方式讀取。
翻譯前應該把 TXT 檔案轉換成 EPUB 或 DOCX 嗎?
只有當你想要那些格式額外提供的功能時才需要。一個章節分明、乾淨的 TXT 檔本身就能翻譯得很好。如果你想要目錄、章節導覽,以及可在裝置上閱讀的電子書,我們的將網路小說轉換為可翻譯的 EPUB指南有詳細說明。
我可以翻譯混合多種語言的 TXT 檔嗎?
可以,但要告訴翻譯工具哪些內容不要更動。第三種語言的引文或術語,以及應保留原文拼寫的姓名,用詞彙表或簡短指示來保護,會比事後修正來得容易。
那從網站下載的 TXT 檔呢?
請確認你有使用該檔案的權利。對於公共領域的書籍或你自己撰寫的檔案,上述步驟均適用。檔案的編碼或格式並不能說明其著作權狀態。





