本文微信公眾號「AndroidTraveler」首發,
背景
最近,要重裝 macOS,所以需要拷貝資料進行備份,
而這個備份程序差點讓我抓狂,速度超級慢,等待時間很是煎熬,
分析
這邊看了一下,主要是因為檔案過多對資料遷移速度造成了較大的影響,
大家知道,我們用 AndroidStudio 新建一個 HelloWorld 專案,系統會自動幫我們生成很多檔案,
這邊建了一個,并查看了檔案(包括目錄)數目,有 85 個檔案,這還是最簡單的專案,
假設一般的專案平均 1000 個檔案,有 100 個專案則檔案數目達到 10 萬級別,(PS:我遇到過一個專案就高達 5 萬多個檔案數目的)
如果你直接拷貝的話,那么耗時是非常長的,尤其是對于機械硬碟而言,
那么我們能否壓縮一下呢?
這么大量的檔案,如果你一次性全部壓縮成一個檔案,那么耗時也是比較大的,
因此這邊就想可否每個專案單獨壓縮,這樣耗時是不是就相對要少一些呢?
但是直接在 mac 上面右鍵并沒有批量壓縮選項,
選擇多個系統會以為你要把多個目錄壓縮成一個檔案,
我們知道,壓縮檔案可以使用命令列,
所以我們可以通過腳本來實作批處理壓縮檔案,
實戰
那下面我們就一步一步來完成批處理壓縮腳本的撰寫,
Step 1: 創建并運行腳本
我們假設創建的腳本名字為 batch_zip.sh,
在終端上執行下面命令:
touch batch_zip.sh;chmod u+x batch_zip.sh
第一條命令是創建 batch_zip.sh 檔案,第二個命令是為該檔案增加可執行權限,因為我們的腳本最后是需要運行的,
如果你是直接拷貝我文末鏈接上的腳本檔案,你下載到本地只需要執行第二條命令即可,
Step 2: 熟悉壓縮命令
首先我們需要了解壓縮命令,最基本的壓縮命令如下:
zip 壓縮后檔案.zip 壓縮前檔案
由于我們有遞回壓縮需求,因此需要添加 -r 選項,
另外壓縮程序默認會顯示壓縮詳情,比如具體壓縮了哪些檔案,
如果你不想知道具體壓縮程序,可以添加 -q 選項,
我們將這兩個選項組合起來,最終壓縮命令就是:
zip -rq 壓縮后檔案.zip 壓縮前檔案
你以為這就結束了?
假設壓縮前的檔案命名帶有空格,你直接用上面的命令,那么會出現意想不到的結果,所以為了應對這種情況,我們需要稍作修改,給檔案名加個引號(單引號雙引號都可以)括起來,
zip -rq '壓縮后檔案.zip' '壓縮前檔案'
Step 3: 羅列當前目錄的所有檔案
我們知道,羅列當前目錄所有檔案只需要使用 ls 命令即可,
所以我們將這個命令回傳的結果集用一個變數保存起來,然后我們列印看下效果,
我們修改我們的腳本檔案,修改后如下:
FILES=`ls`
echo $FILES
注意這里不是單引號,這里的符號位置在鍵盤左上角處,
然后我們運行腳本:
./batch_zip.sh
就可以看到羅列出的檔案了,
Step 4: 回圈遍歷所有檔案
因為我們的檔案都放在集合里面,因此我們需要逐個遍歷獲取,然后逐個進行壓縮操作,
這里用到了回圈陳述句,基本結構如下:
for element in array
do
// TODO
done
// TODO 里面就是你具體要處理的事情,
所以我們可以修改腳本檔案如下:
FILES=`ls`
for file in $FILES
do
echo $file
done
這樣運行之后就會逐個列印羅列后的檔案名,
如果你當前目錄有檔案的名字是包含空格的話,你會發現列印出來的有空格檔案名被隔開了,
比如你的檔案名是 test 2.txt,則列印會列印出兩行,分別是 test 和 2.txt,
因為 ls 命令列出的不同檔案就是用空格隔開的,
所以一般情況下推薦命名不要有空格,如果需要分隔,可以用下劃線 _,
但是假設真的有怎么辦?
別慌,問題不大,
直接 show 代碼如下:
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for file in *
do
echo $file
done
IFS=$SAVEIFS
具體腳本分析我們就不展開了,大家感興趣可以看文末參考鏈接,
Step 5: 只壓縮目錄
其實我們壓縮的是對于包含大量瑣碎檔案的目錄,因此只需要壓縮目錄就可以了,
另外我們的腳本檔案因為是檔案,包括壓縮檔案也是普通檔案,因此不需要額外進行排除,
改造后代碼如下:
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for file in *
do
if [ -d $file ]
then
echo $file
fi
done
IFS=$SAVEIFS
修改點在 do-done 塊里面,
主要是增加了一個判斷,當檔案是目錄時,才執行列印操作,
Step 6: 替換列印為壓縮命令
結合 Step2 我們最終的腳本命令為:
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for file in *
do
if [ -d $file ]
then
zip -rq $file.zip $file
echo $file was successfully compressed.
fi
done
IFS=$SAVEIFS
壓縮成功每個檔案都會列印一句壓縮成功,
使用
只需要將腳本命令拷貝到你需要壓縮的目錄下面,就可以對跟腳本檔案同級的所有目錄進行壓縮,
記得腳本檔案需要有可執行權限才能運行,
如果提示沒有權限,可以先運行如下命令添加權限,
chmod u+x batch_zip.sh
下載
大家可以到 GitHub 倉庫上面去直接下載本文最終生成的腳本檔案,
https://github.com/nesger/EffectiveTools/blob/master/shell/batch_zip.sh
里面的 README.md 也有具體的用法說明,
優化點
這個腳本命令還有很多地方可以優化,有待大家去完善,
這里列舉如下;
- 支持壓縮指定目錄而不是固定為當前目錄,指定目錄通過執行腳本時引數帶入
- 壓縮結束后告知本次成功壓縮的總數目
- 增加一個邏輯判斷,壓縮成功后是否洗掉原檔案?可以通過執行腳本時引數帶入
這里就不再描述了,相信對于讀者來說,要實作這些優化也是很簡單的事情,
溫馨提示
其實如果你是要換機器,而且當前系統沒有 bug 的話,
推薦使用時間機器(Time Machine)進行系統遷移,
它相當于把你一臺機器上的整個系統(包括檔案)進行一個遷移,省去了你重新安裝應用程式和搭建環境的時間,
參考鏈接:
https://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html
https://www.cnblogs.com/cocowool/archive/2013/01/15/2861904.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/179648.html
標籤:其他
上一篇:阿里架構師:天天高并發,達不到百萬以上并發都不叫高并發!!
下一篇:總有開始,開花亦結果
