Learning Objectives
- 用 file 判斷檔案的格式,用 tar -tvf 先看打包檔裡有什麼再解開
- 比較 cat、more、less 讀取打包檔的差異,用 zcat/bzcat/xzcat 不解壓縮就看內容
- 用 gunzip、bunzip2、unxz(或 -d)解壓縮,用 -k 保留壓縮檔
- 用 tar -xvf 解開打包檔,用 -C 指定解開的位置;用 unzip -l 查看、unzip -d 解開 zip 檔
拿到一個壓縮檔,先看清楚再解開
上一課把檔案打包、壓縮;這一課反過來。拿到別人給的 something.tar.gz 時,建議依序做三件事:
- 它是什麼格式? 用
file看檔案的真實格式,副檔名只是名字,可能取錯 - 裡面有什麼? 用
tar -tvf、unzip -l先列出內容,確認不會把一堆檔案灑在目前目錄、也不會覆蓋同名檔案 - 要解到哪裡? 用
tar -C、unzip -d指定目的地
$ file a.tar.gz samba.tar notes.txt
a.tar.gz: gzip compressed data, from Unix
samba.tar: POSIX tar archive (GNU)
notes.txt: ASCII text
| 格式 | 解壓縮 | 不解壓縮直接看內容 |
|---|---|---|
.gz |
gunzip 檔案 或 gzip -d 檔案 |
zcat、zless、zgrep |
.bz2 |
bunzip2 檔案 或 bzip2 -d 檔案 |
bzcat、bzmore、bzless |
.xz |
unxz 檔案 或 xz -d 檔案 |
xzcat、xzless |
.tar、.tar.gz、.tar.bz2、.tar.xz |
tar -xvf 檔案 |
tar -tvf 檔案(只列清單) |
.zip |
unzip 檔案 |
unzip -l 檔案(只列清單) |
檢視打包檔與壓縮檔
打包檔(.tar)不是文字檔。 tar 在每個檔案前面加上一段檔頭(檔名、權限、擁有者、大小),所以:
| 指令 | 讀 samba.tar 的結果 |
|---|---|
cat samba.tar |
把檔頭與檔案內容一起印出來,檔名夾雜一堆看不懂的字元 |
more samba.tar |
和 cat 一樣,只是一頁一頁顯示 |
less samba.tar |
先問 "samba.tar" may be a binary file. See it anyway?;在 Ubuntu 上,家目錄的 .bashrc 預設啟用 lesspipe,less 會直接顯示打包檔的檔案清單 |
tar -tvf samba.tar |
整齊地列出每個檔案的權限、擁有者、大小、時間與路徑 |
要看清單,用 tar -tvf 最可靠;要看其中一個檔案的內容,先解開再讀。
壓縮檔(.gz/.bz2/.xz) 可以不解壓縮直接看內容,指令名稱是在原本的指令前面加上 z、bz、xz:
zcat a.gz # 等於解壓縮後 cat,但不產生檔案
bzless xattr.conf.bz2 # 用 less 的方式翻頁,可以按 / 搜尋
zgrep -n global smb.conf.gz # 在壓縮檔裡搜尋 global,-n 顯示行號
解壓縮單一檔案
gunzip a.txt.gz # 得到 a.txt,a.txt.gz 消失;等於 gzip -d a.txt.gz
bunzip2 -k b.txt.bz2 # 得到 b.txt,-k 保留 b.txt.bz2;等於 bzip2 -dk b.txt.bz2
unxz c.txt.xz # 得到 c.txt;等於 xz -d c.txt.xz
和壓縮一樣,預設會用解壓縮後的檔案取代壓縮檔,加 -k 才會保留。
目錄裡已經有同名檔案時,三個程式都會停下來:gunzip 會詢問是否覆蓋,bunzip2 與 unxz 會回報檔案已經存在、不解壓縮。
確定要覆蓋時加 -f,或先把舊檔案改名。
tar -x:解開打包檔
tar -xvf 打包檔 [-C 目的地目錄] [只要解開的檔案...]
| 選項 | 意思 |
|---|---|
-x |
解開;和 -c、-t 三選一 |
-v |
列出正在解開的檔案 |
-f 檔名 |
要解開的打包檔 |
-C 目錄 |
先切換到這個目錄再解開;目錄必須已經存在,不存在時會出現 Cannot chdir: No such file or directory |
-z、-j、-J |
指定用 gzip、bzip2、xz 解壓縮 |
解開時通常不需要 -z、-j、-J。 GNU tar 讀取打包檔時,會依檔案開頭的特徵自動判斷壓縮格式,所以 tar -xvf a.tar.gz、tar -xvf a.tar.bz2、tar -xvf a.tar.xz 都可以。
投影片的 tar zxvf filename.tar.gz 也正確,只是 z 可以省略。從管線讀入(例如 curl ... | tar -xz)時無法自動判斷,才一定要寫。
常見寫法:
tar -xvf etc.tar.gz # 解開到目前所在的目錄
mkdir ~/data && tar -xvf etc.tar.gz -C ~/data # 解開到 ~/data
tar -xzvf /tmp/etc.tar.gz etc # 只取出打包檔裡的 etc 目錄
tar -xvf a.tar.xz etc/samba/smb.conf # 只取出一個檔案;路徑要和 tar -tf 列出的一模一樣
打包檔裡的路徑已經去掉開頭的
/,所以tar -xvf a.tar.gz會在目前目錄建立etc/samba/...,不會覆蓋系統的/etc/samba。 想直接還原到原本的位置,才需要sudo tar -xvf a.tar.gz -C /,執行前務必先用-t看清楚內容。
unzip
unzip -l samba.zip # 只列出內容
unzip samba.zip # 解開到目前目錄
unzip samba.zip -d /tmp/unzipped # 解開到指定目錄;目錄不存在會自動建立
和 zip 一樣,Ubuntu Server 可能沒有預先安裝 unzip,沒有時用 sudo apt install zip unzip。
想一想:檢視與解壓縮
拿到一個叫 data.bin 的檔案,不知道是什麼格式,最直接的檢查方式是?
想看 notes.txt.gz 的內容,但不想產生解壓縮後的檔案,應該用?
執行 bunzip2 report.bz2 之後,目錄裡會有什麼?
想一想:解開打包檔
關於 tar -xvf backup.tar.xz(沒有加 -J),下列何者正確?
tar -xvf site.tar.gz -C /srv/www 出現 Cannot chdir: No such file or directory,原因是?
想先確認 photos.zip 裡有哪些檔案、不要解開,應該用?
重點精華回顧
- 解開前先看清楚:
file判斷格式,tar -tvf、unzip -l列出內容。 - 打包檔不是文字檔:
cat、more會印出檔頭與內容混在一起,tar -tvf才是整齊的清單。 zcat、bzcat、xzcat(以及zless、bzless、zgrep)可以不解壓縮直接看內容。gunzip、bunzip2、unxz(或-d)解壓縮,預設取代壓縮檔,-k保留。tar -xvf解開打包檔,GNU tar 會自動判斷壓縮格式;-C指定目的地,目錄要先存在;後面接路徑可以只取出部分檔案。unzip -d 目錄解開 zip 檔,目錄不存在會自動建立。