先分流:你比的是什麼
「找出兩段文字哪裡不一樣」這個需求,輸入長什麼樣決定了正確做法:
| 你要比的 | 正確姿勢 | 為什麼 |
|---|---|---|
| 兩版設定、兩段日誌、兩版程式碼/文件 | 直接貼進文字對比工具(如本站 文字差異對比器) | 順序就是語意,逐行 diff 正是對的工具 |
| 兩份順序無關的清單(依賴列表、詞表、檔名) | 先各自行排序,再對比 | 順序差異會淹沒成員差異,排序後剩下的全是真實增刪 |
| 兩份 JSON | 別用文字 diff,用 JSON 比對 | 鍵序/空白/轉義製造海量假差異,結構化比對按欄位路徑報告 |
| git 工作區裡的改動 | git diff |
版本系統本來就懂「誰改的、什麼時候改的」,瀏覽器工具是給它善後的 |
前兩行的細節是本文的正題:檢視怎麼讀、假差異怎麼消。
diff 檢視怎麼讀
對比結果有兩種呈現,各有領地:
- 分欄檢視(split):左原文右改文,同一行號左右對齊,改動行高亮。適合「對照著讀」——看清楚每處改動的前後狀態,寬螢幕下效率最高;
- 統一檢視(unified):刪行帶
-前綴、增行帶+前綴,從上往下線性讀。適合逐行審閱、窄螢幕,以及把結果複製給別人——它的形態接近git diff與diff -u的輸出,任何看慣程式碼審查的人都秒懂。
常見節奏是先分欄定位(左右對照快速掃出改動簇),再切統一檢視複查細節。增刪行數統計是第一個該看的數字:它告訴你改動面有多大,決定你用「逐行讀」還是「抽樣讀」。
三類假差異怎麼消
逐行對比的原理是「字串相等的行才算相同」,所以任何與語意無關的字面差異都會被標紅。三類最常見:
空白與大小寫噪音:縮排調整、行尾空格、大小寫變化(設定裡 true 與 True)。開「忽略空白」「忽略大小寫」選項——但要清楚代價:開著它們也可能掩蓋真實改動(把 DEBUG=true 改成 debug=true 的人會漏網)。先關選項看嚴格結果,噪音太多再開,是穩妥順序。
行尾符(CRLF vs LF):Windows 儲存的檔案是 CRLF,Unix 是 LF,逐行對比裡它們是不同的行——一份檔案只是換了個編輯器開啟儲存,就全篇標紅。這是「明明沒改卻滿螢幕紅」的頭號原因,先統一行尾(工具的文字調整選單有一鍵統一)再比。
特殊字元與不可見字元:零寬空格、BOM、裝飾性符號——肉眼看不出但讓行不相等,「忽略特殊字元」選項把標點符號類字元從比對中剔除,恰好也壓掉零寬字元這類隱形噪音。懷疑有不可見字元時,觀察「明明看起來一樣的行被標紅」就是訊號。
整理後再比:兩個高頻招
無序清單先排序:對比兩份依賴列表、兩份詞表時,順序差異會讓 diff 結果全是噪音。先用行排序把兩份各自按字典序排好,再對比——剩下的差異全是成員級的增刪,一眼看清誰多了誰少了。判斷標準就一句話:這份清單的順序本身是不是資訊?不是,就排。
被格式化過的文字先歸一:兩邊各自被不同的編輯器格式化過(縮排、換行風格不同)時,diff 報告的是格式差異而非內容差異。把兩份用同一規則整理(統一行尾、統一縮排策略)再比。JSON 特殊一些:格式化/壓縮的輔助按鈕可以臨時救急,但正解是結構化比對——那不是文字 diff 該扛的活。
真話:邊界在哪裡
- 50 萬字元/側的上限:日誌全量、資料轉存這類超長文字,瀏覽器不是正確的戰場,命令列
diff -u a.txt b.txt沒有這個限制,輸出還能進管道; - 超過 2 份文字的對比:三方合併是 git 的領地,兩兩對比的網頁工具做不了 merge 語意;
- 版本歷史與「誰改的」:文字 diff 只回答「哪裡不同」,不回答「什麼時候、誰、為什麼改的」——這些在版本系統裡。網頁工具的最強場景是手裡只有兩段文字、沒有版本庫的時候:聊天裡貼來的兩段設定、別人寄來的兩版文件、線上環境與本機環境的輸出對照。
常見問題
為什麼明明只改了一行,diff 結果標了一大片?
三個常見原因:一是行尾符不同——Windows 的 CRLF 與 Unix 的 LF 在逐行對比裡是不同的行,一份檔案換了個編輯器儲存就全篇標紅,先統一行尾再比;二是空白差異——縮排變化、行尾空格讓行不相等,開「忽略空白」;三是文字被整體格式化過,此時 diff 結果是真實但無用——先把兩份用同一規則格式化,再比。
怎麼對比兩份順序不同的清單?
先用工具的行排序把兩份清單各自按字典序排好,再對比——順序無關的清單直接比會被順序差異淹沒,排序後剩下的差異全是成員級的增刪。判斷標準想清楚一件事:這份清單的順序本身是不是資訊?是(如優先級列表)就不能排,不是(如依賴集合)就排。
分欄檢視和統一檢視各適合什麼時候用?
分欄(split)適合較寬的螢幕和「左右對照著讀」的場景;統一(unified)適合逐行順序審閱、窄螢幕、以及把結果貼給別人(統一檢視的線性結構接近 git diff 的輸出,溝通成本低)。同一個差異結果兩種檢視零成本切換,先分欄定位、再統一複查是常見節奏。
文字 diff 能比兩份 JSON 嗎?
能貼進去比,但不該:JSON 的鍵序、空白、轉義寫法會讓文字 diff 報出海量假差異,而且一個值的改動會把整行標紅、定位不到具體欄位。比 JSON 用結構化比對——按 JSONPath 報告哪個欄位增刪改,鍵序預設忽略。文字 diff 的領地是設定、日誌、程式碼、文件這類「行本身就是語意單元」的內容。