﻿# 分享幾個常用的 7-Zip 壓縮與解壓縮命令

我們最近幾年幾乎所有案子都導入 CI/CD，把所有能自動化的工作全部都指令化，所以只要公司需要開發時期用的測試機，或是客戶需要安裝主機，通常都可以在 10 分鐘內搞定所有環境與設定。今天這篇文章我要來分享幾個常用的 [7-Zip](https://www.7-zip.org/) 命令與參數，因為 7-Zip 在第一次使用 `7z` 命令的時候，他的使用方式比較沒那麼直覺，所以寫成文章供未來查表參考之用。

![7zip](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/b7d68632dcce99853a8c-9bab8989-d2c1-47cb-90a5-18b85ebb2a83.webp)

### 安裝 7-Zip 工具

一如往常的，我幾乎都使用 Chocolatey 進行安裝 [7-Zip](https://community.chocolatey.org/packages/7zip) 套件：

```powershell
choco install 7zip -y
```

> 請注意要輸入 `7zip` 才是正確的套件名稱喔，這裡的 `7` 與 `zip` 中間不能加上 Dash 符號 (`-`)！

你也可以用微軟最近推出的 [Windows Package Manager CLI](https://github.com/microsoft/winget-cli/) 安裝 [7-Zip](https://github.com/microsoft/winget-pkgs/tree/master/manifests/7/7zip/7zip) 工具

```powershell
winget install 7zip
```

> [Windows Package Manager 1.0 | Windows Command Line](https://devblogs.microsoft.com/commandline/windows-package-manager-1-0/?WT.mc_id=DT-MVP-4015686)

### 常用的**壓縮檔案**命令與參數

1.  壓縮整個資料夾，而且壓縮檔案中的第一層就是該資料夾
    
    **這意味著壓縮檔中第一層目錄中沒有檔案，只有一個資料夾！**
    
    會這樣壓縮，通常是因為「解壓縮的人」經常會使用「解壓縮到這裡」的方式進行解壓縮，如果他把壓縮檔放在「桌面」上，解壓縮的時候就會看到桌面上只有一個檔案，看起來比較乾淨。
    
    壓縮 `dir1\` 資料夾下所有檔案，而且壓縮檔案中會看到 `dir1` 這個資料夾！
    
    ```powershell
    7z a "dir1.zip" "dir1\"
    ```
    
    如果你用以下命令壓縮，將會在壓縮檔中看到 `dir1` 與 `dir2` 資料夾等路徑！
    
    ```powershell
    7z a "dir1.zip" "dir1\dir2\"
    ```
    
    > 7-Zip 預設會壓縮該目錄與所有子目錄的所有檔案！
    
    如果要壓縮成 `*.7z` 格式，不用特別下參數，直接設定好壓縮檔的副檔名即可，例如：
    
    ```powershell
    7z a "dir1.7z" "dir1\"
    ```
    
    > 注意：7-Zip 支援 `*.rar` 的解壓縮，但不能使用 RAR 格式進行，因為 RAR 壓縮格式有專利保護！
    
2.  壓縮整個資料夾，而且壓縮檔案中第一層就是該資料夾下所有檔案與子資料夾
    
    我個人比較喜歡這樣壓縮檔案，許多雲端平台在上傳檔案部署的時候，也會要求要用這種方式壓縮才能正常部署。
    
    壓縮 `dir1\` 資料夾下所有檔案，壓縮檔案不會看到 `dir1` 這個資料夾，只會看到裡面的檔案與子資料夾！
    
    ```powershell
    7z a "dir1.zip" "dir1\*"
    ```
    
    如果你用以下命令壓縮，將會看不到 `dir1` 與 `dir2` 資料夾！
    
    ```powershell
    7z a "dir1.zip" "dir1\dir2\*"
    ```
    
    不過，如果你只想壓縮單一檔案，而且也不希望看見目錄的話，一定要在路徑前面加上一個 `.\` 開頭！
    
    ```powershell
    7z a "dir1.zip" ".\dir1\filename.ext"
    ```
    
3.  壓縮整個資料夾，並且保留現有檔案的完整路徑
    
    由於 7-Zip 壓縮過的檔案不會保留「磁碟代號」，你唯一能做的只能保留「路徑」部份而已。
    
    你可以先進入磁碟的根目錄，然後用上述第 1 種方法來壓縮檔案：
    
    ```powershell
    CD /D G:\
    7z a "dir2.zip" "sub1\dir1\dir2"
    ```
    
4.  只壓縮整個資料夾下的特定檔案類型
    
    如果要壓縮**限定特定類型**的檔案，可以先加上 `-r` 參數，再加上不同的檔名樣式 (File Patterns) 就可以找出檔案並加入壓縮檔：
    
    ```powershell
    7z a "dir1.zip" "dir1\" -r "dir1\*.aspx"
    ```
    
    ```powershell
    7z a "dir1.zip" "dir1\" -r "dir1\*.aspx" "dir1\*.dll"
    ```
    
    如果要**排除特定類型**的檔案**不要進壓縮檔**，可以這樣寫：
    
    ```powershell
    7z a dir1.zip "dir1\" "-xr!*.pdb" "-xr!web.config"
    ```
    
5.  將目前資料夾下的所有檔案壓縮到上一層目錄
    
    如果你想壓縮當前目錄，但是壓縮檔不要出現在本資料夾，可以這樣寫：
    
    ```powershell
    7z a "..\dir1.zip"
    ```
    
    > 不加上任何參數，預設就是把**當前目錄**全部都壓縮起來，但請記得壓縮檔不要放在當前目錄下！
    

### 常用的**解壓縮**檔案命令與參數

1.  解壓縮到當前目錄
    
    請確保不會弄亂你的資料夾才能用這個方法，因為解出來的東西會跟壓縮檔放在一起！
    
    ```powershell
    7z x "dir1.zip"
    ```
    
2.  解壓縮到指定輸出目錄
    
    ```powershell
    7z x "dir1.zip" -o"dir1"
    ```
    
    請記得習慣在 `-o` 參數後面加上 `"` 雙引號，這樣就可以確保資料夾路徑中有**空白字元**也可以正常運作！
    
    ```powershell
    7z x "dir1.zip" -o"C:\Program Files\"
    ```
    
    > 注意：在 `-o` 與 `Path` 中間不能有任何**空白字元**！
    
3.  只解壓縮**特定檔案類型**到**指定輸出目錄**
    
    以下這個解壓縮命令會**保留這些檔案的路徑**在指定**輸出目錄**！
    
    ```powershell
    7z x "dir1.zip" -o"dir1" -r "*.dll"
    ```
    
    > 注意：7-Zip 並非使用 Windows 的 system wildcard parser，他並不會真的去比對有沒有這些系統檔案，而是傳入字串到 `7z` 命令中，讓 7-Zip 去比對所有檔案！
    
4.  擷取**特定檔案類型**到**指定輸出目錄**
    
    這裡不說「解壓縮」而說「擷取」是因為 7-Zip 有個參數 `e` 就是 [`Extract`](https://sevenzip.osdn.jp/chm/cmdline/commands/extract.htm) (擷取) 的意思。這個參數最大的特點就是【**取出的檔案不會保留壓縮檔中的目錄結構**】，專門用來讓你取出壓縮檔案中的一個或多個檔案。
    
    以下這個擷取命令會**取出所有 `*.js` 檔案**到**指定輸出目錄**！
    
    ```powershell
    7z e "dir1.zip" -o"dir1" -r "*.js"
    ```
    
    如果壓縮檔中檔案很多，很有可能會遇到存在於不同目錄，但是檔名相同的狀況，此時就會出現檔名衝突問你要不要覆蓋的提示。如果不想提示直接覆蓋，可以加上 `-y` 參數：
    
    ```powershell
    7z e "dir1.zip" -o"dir1" -r "*.dll" -y
    ```
    
5.  解壓縮時**略過壓縮檔中的第一層目錄**並**指定輸出目錄**
    
    7-Zip 不像 `tar` 有 `--strip-components=` 這種強大的進階用法，所以使用上比較沒那麼靈活，需要搭配批次檔進行實作！
    
    如果是 PowerShell 的話，可以直接這樣執行：
    
    ```powershell
    7z x .\MyWebsite.zip
    cd "MyWebsite"
    mv "*" "C:\Inetpub\wwwroot"
    cd ..
    rmdir "MyWebSite"
    ```
    
    如果是 Command Prompt 的話，建議安裝 Chocolatey 上有個 [UnxUtils](https://community.chocolatey.org/packages/unxutils) 套件，裡面有超多好用的 Linux 常見命令的 Windows 版本，其中當然包含了 `mv` 命令！
    
    ```powershell
    choco install unxutils -y
    ```
    

### 其他 7-Zip 進階用法

1.  壓縮檔案時包含**解壓縮密碼**
    
    壓縮的時候設定一個密碼(`-p`)，解壓縮檔案的時候必須輸入！
    
    ```powershell
    7z a "dir1.zip" "dir1/" -p"1q2w3e4r"
    ```
    
    壓縮的時候設定一個密碼(`-p`)，並且將壓縮檔的 Header 資訊一併加密，也就是連檔名都一起加密，開啟壓縮檔的時候就要先輸入密碼才知道內容！(僅支援 `*.7z` 壓縮檔格式)
    
    ```powershell
    7z a "dir1.7z" "dir1/" -p"1q2w3e4r"  -mhe
    ```
    
    解壓縮一個加密過的壓縮檔到指定輸出目錄
    
    ```powershell
    7z x "dir1.7z" -o"dir1/" -p"1q2w3e4r"
    ```
    
2.  列出所有檔案清單
    
    我們在自動化的過程中可能會需要先知道壓縮檔中有什麼檔案，此時可以利用 `7z` 的 `l` (List) 命令達成這個目的。
    
    ```powershell
    7z l "dir1.zip"
    ```
    
3.  顯示壓縮檔中完整的技術資訊
    
    你可以從中看出每個檔案的完整資訊，包含 CRC 與各種檔案屬性的細節，非常 Geek 的內容
    
    ```powershell
    7z l "dir1.zip" -slt
    ```
    
4.  連同壓縮 NTFS 的 [alternate streams](https://blog.malwarebytes.com/101/2015/07/introduction-to-alternate-data-streams/) 資訊到壓縮檔中 (`-sns`)
    
    > 我在 2008 年有介紹過這個東西 ▶ [介紹好用工具：Streams 讓你瞭解神秘的 NTFS 檔案系統](/post/2008/07/23/Useful-tools-Streams-let-you-know-the-uncovered-secret-in-NTFS)
    
    壓縮檔案時包含 NTFS Alternate Streams
    
    ```powershell
    7z a a.wim -sns *.txt
    ```
    
    7-Zip 解壓縮的時候預設就會包含 NTFS Alternate Streams 到檔案中
    
    ```powershell
    7z x a.wim
    ```
    
    不想讓 7-Zip 解壓縮的時候包含 NTFS Alternate Streams 可以加上 `-sns` 參數
    
    ```powershell
    7z x a.wim -sns-
    ```
    
    列出壓縮檔案內容時包含 NTFS Alternate Streams 資訊 (加上 `-sns` 參數)
    
    ```powershell
    7z l a.wim -sns
    ```
    

### 相關連結

-   [7-Zip](https://www.7-zip.org/)
-   [7-Zip 繁體中文版官方網站](https://www.developershome.com/7-zip/)
-   [7-Zip Command Line Commands](https://sevenzip.osdn.jp/chm/cmdline/commands/)
