最近,数据迁移差点让我抓狂

本文微信公众号「AndroidTraveler」首发。html

背景

最近,要重装 macOS,因此须要拷贝数据进行备份。git

而这个备份过程差点让我抓狂,速度超级慢,等待时间非常煎熬。github

分析

这边看了一下,主要是由于文件过多对数据迁移速度形成了较大的影响。shell

你们知道,咱们用 AndroidStudio 新建一个 HelloWorld 项目,系统会自动帮咱们生成不少文件。bash

这边建了一个,并查看了文件(包括目录)数目,有 85 个文件,这仍是最简单的项目。微信

假设通常的项目平均 1000 个文件,有 100 个项目则文件数目达到 10 万级别。(PS:我遇到过一个项目就高达 5 万多个文件数目的)优化

若是你直接拷贝的话,那么耗时是很是长的,尤为是对于机械硬盘而言。spa

那么咱们可否压缩一下呢?命令行

这么大量的文件,若是你一次性所有压缩成一个文件,那么耗时也是比较大的。code

所以这边就想能否每一个项目单独压缩,这样耗时是否是就相对要少一些呢?

可是直接在 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,则打印会打印出两行,分别是 test2.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 也有具体的用法说明。

优化点

这个脚本命令还有不少地方能够优化,有待你们去完善。

这里列举以下;

  1. 支持压缩指定目录而不是固定为当前目录,指定目录经过执行脚本时参数带入
  2. 压缩结束后告知本次成功压缩的总数目
  3. 增长一个逻辑判断,压缩成功后是否删除原文件?能够经过执行脚本时参数带入

这里就再也不描述了,相信对于读者来讲,要实现这些优化也是很简单的事情。

舒适提示

其实若是你是要换机器,并且当前系统没有 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

相关文章
相关标签/搜索