[Linux] tar/gzip 檔案壓縮與解壓縮、split/cat檔案分割與合併的實務應用


在接觸Linux的過程中,一定會遇到 tar 這個常用的檔案打包指令,即使你自己不使用,在網路上分享或下載的檔案也常常以這個格式存在,所以想要學習Linux的人,這是一個一定要學會的指令,在這篇文章中,將介紹一下我自己常遇到的一些實務應用,透過例子來了解這個指令的操作,另外,也會提到如何搭配splitcat指令,讓大檔案能夠進行分割、合併,類似我們在Windows上使用Winrar/7-zip來進行檔案的壓縮分割一樣

tar

一、檔案打包、壓縮/解壓縮

首先,你可以在自己的Linux環境上輸入tar –help 或 tar –usage就可以看出其實tar這格指令可以操作的參數還蠻多的,但最常用的還是以下這幾個參數,本文將以這些參數為範例來進行解說

  • c:create,建立新的tar檔
  • v:verbose,詳細列出處理過程
  • f:filename,輸出的tar檔名稱
  • x:extract,擷取出打包的檔案
  • z:使用gzip進行壓縮/解壓縮 (壓縮的工具不只gzip,但本文為以gzip為主要說明對象)
  • C:指定解打包或解壓縮的目錄,要注意的是這參數是大寫的C
  • P:大寫P,保留資料的絕對路徑,若打包時有用到P,則解打包時也需要使用
  • p:小寫p,保留資料的權限與屬性

指令的基本語法
壓縮:tar 參數 輸出檔名 檔案來源
解壓縮:tar 參數 檔案來源

範例一:將目錄或檔案打包成tar檔
以下指令是將「demo」這個目錄(or檔案)打包成「demo.tar」檔,因為有加參數「v」的關係,所以會把處理過程顯示在螢幕上

tar -cvf demo.tar ./demo/

範例二:將目錄或檔案打包壓縮成tar.gz檔

tar只是做打包的動作並無作壓縮的處理,因此在這個範例裡我們多加一個參數「z」,代表會利用gzip再進行壓縮,讓整體的檔案大小更迷你,一般會在副檔名結尾處加上「.gz」以更辨識,當然,若你的壓縮工具並非是gzip,那麼副檔名可能就會不同了
:副檔名的部分也可以簡化成「.tgz」,例如:「demo.tar.gz」→「demo.tgz」

tar -zcvf demo.tar.gz ./demo/

範例三:將tar或tar.gz檔解打包/解壓縮
承上所述,來源檔案有沒有用gzip進行壓縮,我都是用檔名是否以「.gz」為結尾來做為初步的判斷,如果沒有壓縮那麼就是純「解打包」,只要套用參數「x」即可,例如要將「demo.tar」解打包,指令如下:(預設會把檔案解打包至當前目錄下)

tar -xvf demo.tar

若有來源檔案有壓縮,則只要再加上解壓縮的參數「z」,因此,如果要將「demo.tar.gz」解壓縮的話,指令會變成:

tar -zxvf demo.tar.gz

範例四:指定解打包/解壓縮的目錄
範例三的解打包/解壓縮的位置預設都是在當前目錄下,如果要指定某個目錄輸出的話,則要加入「C」這個參數,例如下面指令就是將檔案解壓縮到「 /home/demo」的目錄下

tar -zxvf demo.tar.gz -C /home/demo 

範例五:大量打包目錄或檔案

tar有一個好用的參數-T是一定要學會的:有時候我們想要一次打包很多檔案,而且這些檔案是散落各地的,此時就可以藉由此參數接上一個檔案列表,tar就會依據這裡面的內容一個一個的去打包,讓我們用實例來說明吧,語法如下:

tar -cvf demo.tar -T demo.list

而上面語法中的「demo.list」是可以自訂名稱的,內容則是想要打包的檔案或者目錄,例如:

/home/demo/test
/home/demo/abc.txt

意思是執行完這個指令後,tar會打包「test」這個目錄以下所有的檔案(包含子目錄),以及「abc.txt」這個檔案,所以如果未來有很多不同的檔案或目錄要打包時,只要更新這個檔案就行了
二、大檔案分割與合併
有些時候將檔案分割是必要的,例如我最近遇到的例子就是隨身碟有單檔大小的拷貝限制,遇到這種情況,分割檔案就是一個很好的解決方案。在Linux中,分割檔案的指令為split,其指令參數如下:

  • a:suffix-length,檔案編號的位數,預設為2位
  • b:bytes,指定分割的大小,單位為bytes
  • d:numeric,指定檔案編號改以數字為主,原本預設是英文字母
  • n:CHUNKS number,將檔案平均分割為多少個檔案

指令的基本語法

分割:split 參數 來源檔名 自訂分割檔名
合併:cat 來源檔名 > 目的檔名

範例六:將大檔案分割成小檔

[hello@demo-host demo]$ split -b 100MB demo.tar "demo_part_"

這個指令的意思是:將「demo.tar」檔分割成小檔案,每個檔案大小為100MB,新檔名則以「demo_part_」為開頭(可以不用雙引號括起來),預設的編號會用二位英文字母來做編排,所以可以看到下面執行的結果,其檔案結尾是用「aa、ab、ac、ad…」的方式來編排

[hello@demo-host demo]$ split -b 100MB demo.tar "demo_part_"
[hello@demo-host demo]$ ls -al
總計 623112
drwxrwxr-x.  2 hello hello       102  3月 26 18:43 .
drwxrwxr-x. 11 hello hello      4096  3月 26 18:42 ..
-rw-rw-r--.  1 hello hello 100000000  3月 26 18:43 demo_part_aa
-rw-rw-r--.  1 hello hello 100000000  3月 26 18:43 demo_part_ab
-rw-rw-r--.  1 hello hello 100000000  3月 26 18:43 demo_part_ac
-rw-rw-r--.  1 hello hello  19024640  3月 26 18:43 demo_part_ad
-rw-r--r--.  1 hello hello 319024640  3月 26 17:15 demo.tar

那麼我們可以指定的檔案大小單位是什麼呢?在官方的幫助文件有提到喔,以下就是各位單位大小的描述,基本就是有「B」的就是byte乘1000,沒有「B」的乘1024,舉例來說,1K = 1024 bytes、1KB = 1000 bytes、1M = 1024 * 1024 bytes、 1MB = 1000 * 1000 bytes,以此類推

SIZE is an integer and optional unit (example: 10M is 10*1024*1024). Units
are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB, … (powers of 1000)

若不想用預設的英文字母來編排,則可以使用參數「d」,變成以數字做編排,亦可以加上「a」來指定編排的位數

[hello@demo-host demo]$ split -d -a 3 -b 100MB demo.tar demo_part_

例如在這個範例中,加入了「-d -a 3」等參數,表示要用三位數字進行編排

[hello@demo-host demo]$ split -d -a 3 -b 100MB demo.tar demo_part_
[hello@demo-host demo]$ ls -al
總計 623112
drwxrwxr-x.  2 hello hello       106  3月 26 20:30 .
drwxrwxr-x. 11 hello hello      4096  3月 26 18:42 ..
-rw-rw-r--.  1 hello hello 100000000  3月 26 20:30 demo_part_000
-rw-rw-r--.  1 hello hello 100000000  3月 26 20:30 demo_part_001
-rw-rw-r--.  1 hello hello 100000000  3月 26 20:30 demo_part_002
-rw-rw-r--.  1 hello hello  19024640  3月 26 20:30 demo_part_003
-rw-r--r--.  1 hello hello 319024640  3月 26 17:15 demo.tar

範例七:將大檔案平均分割成N個小檔案
如果懶的指定分割後的單檔大小或者想指定分割後的檔案個數,那麼可利用參數「n」來達成,例如以下的範例就是將「demo.tar」這個檔案平均分割成5個等份,至於單檔大小系統會自動去計算

split -n 5 demo.tar demo_part_

範例八:將小檔案合併
想要將分割後的檔案合併回來,請用「cat」指令來進行:cat後面接要合併的檔案名,如果不想打那麼多小檔案的話,可以用「*」來替代,最後利用「>」符號來將檔案導至輸出檔,範例如下,該範例最後會把檔案還原為「demo_recovery.tar」

cat demo_part_* > demo_recovery.tar

三、tar與split的合併使用
在上面的例子中,都是一個一個指令分開獨自操作,但實際上Linux可以透過管線「|」來連接不同的指令
範例九:壓縮檔案並同時進行分割
在這個範例中,會先進行tar的打包壓縮,然後將結果導至split指令進行分割,這裡比較要注意的是因為tar的輸出結果會直接給split使用,所以不需要特別指定檔名,直接用「」帶過即可

tar zcvf - big_demo | split -b 100MB - "abc.part"
tar zcvf - big_demo | split -d -a 2 -b 5G - "xyz.part"

範例十:還原分割檔並同時進行解壓縮
和上個例子類似,本例是先利用cat將所有的分割檔還原,然後導給tar指令進行解壓縮,同樣的,輸出檔名部分也用「」帶過即可

cat demo_part_* | tar -zxvf -

小結:以上幾個範例在我的Linux使用過程中,出現的機率是相當大的,我個人認為對新手來說,若能熟練這幾個範例的操作,那麼也應該應付大部分的需求了,尤其是tar,請初學者記得要學會喔

延伸閱讀:
[Oracle VM VirtualBox 教學] 以Windows平台安裝Ubuntu(Linux)為例