在 Linux 中對兩個檔案進行逐行差異比對,可以精準顯示哪些行被新增、刪除或保持不變,您完全可以透過瀏覽器使用 Diff Checker 來產生這個比較結果——不需要終端機、不需要上傳、不需要伺服器。這個工具讀取左側的原始文字與右側的修改後文字,並用 JavaScript 對兩者執行一個經典的動態規劃演算法,稱為最長共同子序列(LCS)。這也是 Unix diff 工具、Git 的提交檢視,以及 GitHub 和 GitLab 中並排變更顯示背後所用的相同方法,因此您看到的輸出會與終端機指令所產生的報告對得起來。以開頭的 + 標記的行表示在新版本中新增,以 - 標記的行表示從原始檔案中刪除,底部的簡短摘要會持續累計各項的數量。由於所有處理都在用戶端進行,貼上的兩份檔案內容絕不會離開您的機器,這讓此工具適合用於原始碼、伺服器設定片段,以及任何不應上傳到第三方後端的文字內容。

Linux 檔案比對的應用場景
比對文字檔的兩個版本是 Linux 機器上的例行工作,而會用到它的情境總是一再重複相同的模式。以下列舉一些常見情況:
- 設定漂移。兩台伺服器應該共用相同的 nginx.conf 或 sshd_config,但其中一台被人工修改過。差異比對可以精準標出漂移的那一行。
- 提交前的程式碼審查。您在本地重寫了一個函式,想在暫存之前確認這個改動既小又有明確意圖。
- 日誌分析。將同一個服務在部署前與部署後所擷取的兩份記錄進行差異比對,可以找出新出現的紀錄。
- 腳本更新。同事寄給您一份修改過的 Bash 或 Python 腳本,您想確認只有他們提到的那些行有變動。
- 範本與已填寫表單的對照。將空白的 YAML 或 INI 範本與已填寫的版本並排,可看出哪些欄位已填寫、哪些維持預設值。
- 檔案身分驗證。同一份資料集的兩份匯出應該位元完全相同,零行差異就能迅速證明這一點。
上述每個情境都有相同的形態:兩個文字檔、一個關於哪些行有變動的問題,以及不需要合併或重寫文件。
在 Linux 上比對兩個檔案:終端機指令與瀏覽器替代方案
在 Linux 系統上,原生的檔案比對方式是 diff 指令,它屬於 GNU coreutils 已有數十年。最簡單的呼叫方式會列出有差異的行:
diff original.txt changed.txt
加上 -u 可以取得統一格式(unified format),在每個變更處顯示幾行上下文,這也是 git diff 和大多數程式碼審查工具所使用的格式。多數發行版內建的其他選項還包括 colordiff(相同輸出但加上終端機色彩)、vimdiff(在 Vim 內的並排檢視),以及 meld 或 diffuse,提供圖形化的三方合併。這些工具全部在本機執行、不需要網路,且在您能透過 shell 存取得該機器的檔案時是可靠的選擇。
取捨之處在於摩擦力。您需要先安裝套件、需要一個終端機工作階段,並且必須在執行指令的同一處讀取結果。如果檔案存放在您無法管理的工作站上,或是您正在使用 Chromebook、受到管理的筆記型電腦,或無法安裝套件的沙箱環境,那些選項就不一定可用。在這些情況下,基於瀏覽器的差異工具是務實的替代方案:開啟 Diff Checker,把兩份檔案內容分別貼入兩個輸入框,就能讀到與 diff -u 相同類型的逐行報告,省去安裝步驟。
在瀏覽器中執行差異檢查
不論兩個檔案存放在磁碟的哪裡,瀏覽器的操作流程都相同:把內容複製到兩個文字框中,然後讀取下方的報告。
- 在任何現代瀏覽器中開啟 Diff Checker。無需登入、無需擴充套件、無需安裝步驟。
- 將原始檔案的內容貼到標示為「Original」的左側框中。簡單的 cat file.txt 或從編輯器複製都足夠。
- 將新版本的內容貼到標示為「Changed」的右側框中。
- 讀取兩個框下方的逐行結果。以 + 開頭的行表示在新版本中新增;以 - 開頭的行表示從原始版本中刪除;沒有標記的行表示保持不變。
- 查看結果下方的摘要,確認新增、刪除和未變動行的數量。比較會隨著您的輸入即時更新,因此您可以不斷編輯任一側,即時觀察差異重新計算。
對於日常的腳本、設定檔和文件草稿,這個比較幾乎是即時的。
解讀輸出:+、- 和計數的意義
+ 代表新增、- 代表刪除,這個視覺慣例與 diff -u 所用的相同,所以任何看過修補檔(patch)的人都能一眼認出。真正有趣的部分是當您在長檔案中間修改一行時,哪些內容仍然保持對齊。這個工具並非單純地將第 1 行對第 1 行、第 2 行對第 2 行依序比較;它會先找出兩個檔案中以相同順序出現的最長連續行,並把該序列視為共享骨幹。骨幹以外的所有內容則會被回報為新增或刪除。淨效果是:在 200 行的檔案中修改第 47 行時,會在第 47 行位置顯示為一行刪除與一行新增,而第 48 行到第 200 行則保持對齊且不被標記。
這種方法稱為最長共同子序列演算法,與驅動 Unix diff 工具、Git 的比較檢視,以及託管 Git 平台並排變更檢視所用的動態規劃技術相同。在解讀輸出時有兩個實際意涵:
- 標記同時使用前置的 + 或 - 以及背景顏色。如果您的檢視器去除了顏色(無色彩支援的終端機、列印出來的紙本、貼到純文字筆記中),標記本身仍能傳達變更。
- 即使只有單一字元不同的行,也會被回報為一條刪除加一條新增,而不是部分的就地修改。這對原始碼、設定檔和散文來說是正確的粒度,因為這些場景中有意義的變更單位是整行。
結果底部的摘要會加上三個總計:新增的行數、刪除的行數,以及在兩個檔案中以未變動形式出現的行數。在一次乾淨的稽核中——也就是兩個檔案完全相同——新增和刪除欄會顯示為零,每一行都會被計入未變動。
逐行差異擅長處理的場景
逐行比對是處理 Linux 使用者每天接觸的文字檔類型的合適工具,但對少數邊界情況並不適合。下表總結了其適用程度。
| 檔案或內容類型 | 逐行差異是否合適? | 預期結果 |
|---|---|---|
| 原始碼(任何語言) | 是 | 每一行都是自然的單位;整行的變更是常見的提交形式。 |
| 設定檔(nginx、sshd、systemd 單元) | 是 | 像新增一條 listen 指令這樣的單行變更會顯示為一處新增或刪除。 |
| 日誌檔(syslog、journald 匯出) | 是 | 新增或刪除的日誌行會立即可見。 |
| JSON、YAML、TOML | 是(需先格式化) | 請先進行美化排版,讓有意義的行能對齊;壓縮的 JSON 會產生雜亂的差異。 |
| CSV | 是 | 每一列就是一行,因此新增或刪除的列會一目了然。 |
| 散文與 Markdown | 是 | 段落能乾淨地對應到行;單一字元的打錯仍會顯示為一行刪除與一行新增。 |
| 編譯後的二進位檔、影像、封存檔 | 否 | 請改用 cmp 或 xxd 等十六進位工具;逐行的文字差異在這裡沒有意義。 |
如果您在意長行內部單一字元的編輯,逐行差異會並排顯示整行舊內容與整行新內容,您可以用肉眼讀出差異。若要在 JSON 等結構化格式中達到字元等級的精確度,針對已剖析樹狀結構進行結構性差異會更合適;但對於日常的「這個檔案改了什麼」這個問題,逐行差異在 Linux 及其他環境都是標準答案。
讓敏感的 Linux 檔案不經網路外傳
Linux 伺服器上存放著許多值得進行差異比對、卻又不應離開機器的文字:~/.ssh/config 中的私密 SSH 金鑰、.env 檔中的內部 API token、未發佈的文件、客戶資料匯出、已簽署的合約,以及專有的原始碼。大多數線上差異工具會透過 POST 將您的文字送到後端,這代表您檔案的內容會在取得結果的途中經過第三方伺服器。
Diff Checker 走的是不同的路。您貼上的兩段文字完全在瀏覽器中使用 JavaScript 進行比對,因此沒有任何網路請求會將檔案內容外帶。關閉分頁就會捨棄記憶體中的資料,重新整理頁面則會重起一個全新的狀態。取捨之處在於,極大的輸入(數千行以上)會按比例消耗更多記憶體;但對於日常適合單一螢幕顯示的腳本、設定和文件草稿,比較既快速又保持在本地。如果您經常處理不應離開機器的資料,這種隱私立場通常才是決定要選用終端機差異工具還是瀏覽器版工具的關鍵因素。
延伸閱讀:如何從路徑清單產生 Linux 目錄樹。
延伸閱讀:如何在 Linux 中建立 Cron 工作。