作者:田逸(sery@163.com)

因为审查的原因,大量的app包需要删除。这些包位于不同的目录下,不能直接清空目录,因此要删除这些文件,还是比较麻烦的。有关部门给了一个完整的删除列表,我检查了一下,共有324130,这些文件小的几个KB,大的数百兆。起初我吩咐小弟去干,干了一阵,反馈说文件太多,rm不起作用。我抽空去看了一下他写的脚本,内容截取如下:

[root@sdyd163 del_soft]# more /root/del.sh 
/bin/rm -rf /mnt/nfs_dir/soft/2015/10/28/103/1033350/TDtafangshouweizhan_V8.1_mumayi_1a058.apk
/bin/rm -rf /mnt/nfs_dir/soft/2015/05/21/97/972733/zhongguotaociwang_Vv1.8.1.0303_mumayi_05f30.apk
/bin/rm -rf /mnt/nfs_dir/soft/2014/09/26/84/848499/koudaiyaoguai_shuiyin_V1.4.0_mumayi_82dcc.apk
/bin/rm -rf /mnt/nfs_dir/soft/2013/08/16/38/383759/quanhuang99duizhanban_V3.3.13_mumayi_ab8ce.apk
/bin/rm -rf /mnt/nfs_dir/soft/2013/12/17/47/473845/longyin_V4.28_mumayi_bb436.apk
/bin/rm -rf /mnt/nfs_dir/soft/2013/12/16/47/473291/zhimingfeichedang_V1.0.0_mumayi_79418.apk
/bin/rm -rf /mnt/nfs_dir/soft/2013/12/16/47/473292/jiangshilaixi_V16_mumayi_eadd5.apk
/bin/rm -rf /mnt/nfs_dir/soft/10/donghuarenwudaluandou_V1.1_mumayi_a1476.apk
/bin/rm -rf /mnt/nfs_dir/soft/12/huweijiaodoushi_V1.1_mumayi_ca2b7.apk
/bin/rm -rf /mnt/nfs_dir/soft/14/pensijiangshi_V1.0_mumayi_03868.apk
/bin/rm -rf /mnt/nfs_dir/soft/15/yongzhezhengtu_V1.06_mumayi_81f4c.apk
/bin/rm -rf /mnt/nfs_dir/soft/2013/06/26/0/20/dushisaiche5zhongwenban_V3.0.3_mumayi_dc6de.apk
/bin/rm -rf /mnt/nfs_dir/soft/2010/10/15/21/zhiwudazhanjiangshizhanlueban_V3.0_mumayi_b6c2e.apk
/bin/rm -rf /mnt/nfs_dir/soft/2010/10/23/33/datuzi_V1.0_mumayi_640a4.apk
/bin/rm -rf /mnt/nfs_dir/soft/2010/10/24/38/kuangretubage_V1.6.3_mumayi_24644.apk
/bin/rm -rf /mnt/nfs_dir/soft/2010/10/24/40/emoshashou_V1.0.2_mumayi_a1c65.apk
……………………………………….省略……………………..

这种方式不但没有效率,而且根本进行不下去,需要改进。

基本思路是:把这些文件都移动到某个目录,然后干掉整个目录。为了保证不误删、不发生意外,先从他这个脚本把文件名提取出来,专门生成一个文件,命令如下:

[root@sdyd163 del_soft]# awk '{print $NF}' /root/del.sh >/root/large_files_del.txt

再写一个脚本,查看这些文件是否存在,脚本内容如下:
#先生成一个小文件列表

head -1000 /root/large_files_del.txt > /root/1000files.txt

#查看文件是否存在(有好些文件是不存在的)

[root@sdyd163 del_soft]#more /root/listfiles.sh
#!/bin/bash

for file in `cat /root/1000files.txt`
do
 if [ -e $file ]
then  
echo $file
fi
done

执行完毕,居然没有文件输出,这意味着所有文件不存在,怎么可能呢?在文件列表中随机抽取几个,用ls 检索,有些文件确实存在啊!莫非文件列表有问题?vi打开/root/1000files,文件居然是windows格式。
老司机巧删巨量文件
用dos2unix进行格式转换,再执行/root/listfiles.sh,可以看到输出(仅输出存在的文件)。为什么dos格式查不到文件存在呢?那是因为文件列表的每一行行尾有一个\r存在
老司机巧删巨量文件

确信欲删除的文件存在以后,在前边的这个脚本基础上稍微改进一下,主要目的就是把存在的文件移动到指定的目录。注意,因为文件巨多,而且占用的空间很大,需要考虑目标目录有足够的空间来保存这些巨量文件,确定有足够的空间以后,创建目录/mnt/nfs_dir/del_soft/待用。修改后的脚本如下:

[root@sdyd163 del_soft]# more /root/mv_files.sh
#!/bin/bash

for file in `cat large_files_del.txt`
do
mv $file /mnt/nfs_dir/del_soft/
done

此脚本无需加判断语句,因为mv过程会自行判断,如果不存在,它会自动跳过。给此脚本赋予执行权限,然后开一个screen,在此screen下执行脚本/root/mv_files.sh。再开一个shell窗口,进入目录/mnt/nfs_dir/del_soft,可查看到移动过来的文件,并且随时间增加而增加。
老司机巧删巨量文件

待脚本/root/mv_files.sh执行完毕,所有需要删除的文件都移动到指定目录/mnt/nfs_dir/del_soft,在系统上创建一个空目录/root/sery,然后用rsync把这个/mnt/nfs_dir/del_soft目录的文件连根拔起,子子孙孙都干掉。具体指令如下:

[root@sdyd163 ~]# rsync --delete-before --force -r /root/sery/  /mnt/nfs_dir/del_soft

执行脚本前,总文件数是84886,占用空间644G。
老司机巧删巨量文件
执行这个脚本,大概耗时数十分钟,解决了用rm不能删除的麻烦。

最后,和大家分享我的订阅专栏《负载均衡高手炼成记》,本专栏依托作者十余年IT运维经验,从入门到实操,手把手教你构建运行不同场景下负载均衡以及日常维护。
老司机巧删巨量文件