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


    本文微信公众号「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,则打印会打印出两行,分别是 test2.txt

    因为 ls 命令列出的不同文件就是用空格隔开的。

    所以一般情况下推荐命名不要有空格,如果需要分隔,可以用下划线 _。

    但是假设真的有怎么办?

    别慌,问题不大。

    直接 show 代码如下:

    #!/bin/bash
    SAVEIFS=$IFS
    IFS=$(echo -en "
    ")
    
    for file in *
    do
      echo $file
    done
    
    IFS=$SAVEIFS
    

    具体脚本分析我们就不展开了。大家感兴趣可以看文末参考链接。

    Step 5: 只压缩目录

    其实我们压缩的是对于包含大量琐碎文件的目录,因此只需要压缩目录就可以了。

    另外我们的脚本文件因为是文件,包括压缩文件也是普通文件,因此不需要额外进行排除。

    改造后代码如下:

    #!/bin/bash
    SAVEIFS=$IFS
    IFS=$(echo -en "
    ")
    
    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 "
    ")
    
    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

  • 相关阅读:
    Linux系统下设置Tomcat开机自动启动
    2、nginx配置文件基本介绍
    1、Centos7下安装nginx
    40、springboot——运行状态监控使用Actuator
    39、springboot——热部署
    38、springboot——分布式之SpringCloud
    38、springboot——分布式之zookeeper+dubbo
    37、springboot——安全
    36、springboot——异步任务、定时任务、邮件任务
    React过誉了吗?
  • 原文地址:https://www.cnblogs.com/nesger/p/11968766.html
Copyright © 2020-2023  润新知