【shell】将大的图片压缩包zip拆解成小的压缩包

2019-04-15 16:12发布

重要步骤
1、解压压缩包到指定目录;
2、从解压目录中筛选出大小过大的图片移动到别的文件,大小过大的图片手动减少大小后再处理;
3、当解压目录中还有图片时,从解压后的目录中选取一定数量(比如100张)的图片移动到另外一个文件夹A;
4、压缩文件夹A,若新压缩包过大,则删除压缩包,并将文件夹A中一半图片移回原来的解压目录,重新压缩文件A并重复后续动作,直到新压缩包大小满足要求;
5、重复3、4步骤直到解压目录没有图片,操作结束。 split.sh #!/bin/bash #******************************************************* # 本脚本用以将图片数量巨大的压缩包文件拆解成小的压缩包 * # 以便以小的压缩包为单位使用 * # 【重要】要求大的压缩包文件内没有目录结构 * #******************************************************* # 压缩包文件名,不带文件后缀名 zip_file_name="$1" # 当前目录 CURRENT_DIR="$(cd `dirname $0`; pwd)" # 解压目录 UNZIP_DIR="${CURRENT_DIR}/${zip_file_name}" # 图片目录 PIC_DIR="${CURRENT_DIR}/pic" # 压缩包目录,存放小压缩包 ZIP_DIR="${CURRENT_DIR}/zip" # 大图片优化目录 OPT_DIR="${CURRENT_DIR}/optimize" # 压缩包文件大小最大值:30M ZIP_MAX_SIZE="$((30*1024*1024))" # 图片文件大小最大值:2M PIC_MAX_SIZE="$((2*1024*1024))" # 压缩图片 function zipPic() { img_num=$1 # 从解压目录移出100张图片到图片目录 ls "${UNZIP_DIR}" | tail -"${img_num}" | xargs -i mv "${UNZIP_DIR}"/{} "${PIC_DIR}" # 压缩图片 zip "${ZIP_DIR}/${count}.zip" pic/* # 校验压缩包大小 zip_size=`ls -l "${ZIP_DIR}/${count}.zip" | awk '{ print $5 }'` half_num=${img_num} while [ "${zip_size}" -gt "${ZIP_MAX_SIZE}" ] do # 删除压缩包 rm -rf "${ZIP_DIR}/${count}.zip" # 移回图片目录下一半的图片到解压目录 half_num="$((${half_num}/2))" ls "${PIC_DIR}" | tail -"${half_num}" | xargs -i mv "${PIC_DIR}"/{} "${UNZIP_DIR}" # 重新压缩 zip "${ZIP_DIR}/${count}.zip" pic/* zip_size=`ls -l "${ZIP_DIR}/${count}.zip" | awk '{ print $5 }'` done # 清理图片目录 rm -rf "${PIC_DIR}"/* } # 优化图片,无损压缩,支持jpg,需要安装jpegoptim function optimizePic() { find "${OPT_DIR}" -name '*.jpg' | xargs jpegoptim --strip-all echo "$(date +%Y-%m-%d %H:%M:%S): 无损压缩图片完成。" } # 创建目录 function createDir() { # 创建图片目录用以存放要压缩的图片 if [ -d "${PIC_DIR}" ];then rm -rf "${PIC_DIR}" fi mkdir "${PIC_DIR}" # 创建压缩目录用以存放小压缩包 if [ -d "${ZIP_DIR}" ];then rm -rf "${ZIP_DIR}" fi mkdir "${ZIP_DIR}" # 创建大图片优化目录用以存放单张大小超过2M的图片 if [ -d "${OPT_DIR}" ];then rm -rf "${OPT_DIR}" fi mkdir "${OPT_DIR}" echo "$(date +%Y-%m-%d %H:%M:%S): 创建目录完成。" } # 解压ZIP压缩包到解压目录下 function unzipTarget() { if [ -d "${UNZIP_DIR}" ];then rm -rf "${UNZIP_DIR}" fi unzip -o -d "${UNZIP_DIR}" "${zip_file_name}.zip" echo "$(date +%Y-%m-%d %H:%M:%S): 解压目标压缩包完成。" } # 检查单张图片大小是否大于2M function checkPic() { for filename in `ls "${UNZIP_DIR}"` do file_size=`ls -l "${UNZIP_DIR}/${filename}" | awk '{ print $5 }'` if [[ "${file_size}" -gt "${PIC_MAX_SIZE}" ]]; then echo "${filename}图片大小大于2M,已移至优化目录,需要手工处理" mv "${UNZIP_DIR}/${filename}" "${OPT_DIR}" fi done echo "$(date +%Y-%m-%d %H:%M:%S): 检查图片大小完成。" } # 重新压缩成小的压缩包 function zipToSmall() { file_count=`ls "${UNZIP_DIR}" -l |grep "^-"|wc -l` count=1 img_num=100 while [ "${file_count}" -gt 0 ] do if [[ "${file_count}" -ge "${img_num}" ]]; then zipPic ${img_num} else zipPic ${file_count} fi file_count=`ls "${UNZIP_DIR}" -l |grep "^-"|wc -l` let count+=1 done echo "$(date +%Y-%m-%d %H:%M:%S): 重新压缩成小的压缩包完成。" } # 清理目录 function clearDir() { rm -rf "${UNZIP_DIR}" rm -rf "${PIC_DIR}" echo "$(date +%Y-%m-%d %H:%M:%S): 清理目录完成。" } echo "$(date +%Y-%m-%d %H:%M:%S): $0脚本执行开始..." createDir unzipTarget checkPic # 无损压缩图片 # optimizePic zipToSmall clearDir echo "$(date +%Y-%m-%d %H:%M:%S): $0脚本执行结束." 例如有压缩包名为image.zip,则脚本执行命令为:sh split.sh image
注意,使用时压缩包和脚本在同一级目录。 代码细节解析
1、解压压缩包 unzip -o -d "${UNZIP_DIR}" "${zip_file_name}.zip" 命令结构:unzip -o -d [target dir] [file name].zip
-d 指定解压目录
-o 表示解压后覆盖已存在的解压目录内容 2、从解压目录移出100张图片到图片目录 ls "${UNZIP_DIR}" | tail -"${img_num}" | xargs -i mv "${UNZIP_DIR}"/{} "${PIC_DIR}" 命令结构:ls [source dir] | tail -[file number] | xargs -i mv [source dir]/{} [target dir]
如果是脚本当前目录,则命令示例为:ls | tail -100 | xargs -i mv {} tmp/
其中[source dir]因为是当前目录则可以省略。 3、压缩图片 zip "${ZIP_DIR}/${count}.zip" pic/* 命令结构:zip [location]/[name].zip [target dir]
zip命令后面跟了两个参数,第一个是新压缩包的存储位置和压缩包名称,第二个是压缩目录位置。
第二个参数还决定了压缩后压缩包内目录结构,当[target dir]是形如"/image/pic"或"image/pic"时,压缩包内结构目录将与之一致,将有两级目录。
若不需要目录结构,增加-j参数即可,则命令可以是:zip -j [location]/[name].zip [target dir] 4、获取压缩包大小 zip_size=`ls -l "${ZIP_DIR}/${count}.zip" | awk '{ print $5 }'` 命令结构:ls -l [file name] | awk ‘{print $5}’
命令的意思是,列出文件详细信息,通过awk命令获取第5个参数值。例如:
在这里插入图片描述
从左往右数,第五个是“101919574”,即文件大小值,单位 bit 5、打印日志 echo "$(date +%Y-%m-%d %H:%M:%S): $0脚本执行开始..." 时间格式:年-月-日 时:分:秒
$0 获取的是当前脚本名称 6、获取目录下文件数量 file_count=`ls "${UNZIP_DIR}" -l |grep "^-"|wc -l` 命令结构:ls [target dir] -l | grep “^-” | wc -l 7、无损压缩工具安装
在linux环境依次执行以下命令:
1)yum install optipng -y
2)yum install -y libjpeg libjpeg-devel
3)wget http://freecode.com/urls/fbbba65c1ddc8766cf74c3db8d2547a8
该步骤可能下载下来文件名称就叫fbbba65c1ddc8766cf74c3db8d2547a8,则在windows系统浏览器访问 “http://freecode.com/urls/fbbba65c1ddc8766cf74c3db8d2547a8” 会自动下载文件“jpegoptim-1.4.1.tar.gz”,上传到linux环境就好。
4)tar -xvzf jpegoptim-1.4.1.tar.gz
5)cd jpegoptim-1.4.1/
6)./configure
7)make && make install 8、无损压缩 find "${OPT_DIR}" -name '*.jpg' | xargs jpegoptim --strip-all 命令结构:find [target dir] -name [target picture] | xargs jpegoptim --strip-all
命令的意思是,根据名称搜索对应图片并用jpegoptim工具无损压缩。
find [target dir] -name [target file]是常用的查找工具命令格式,如果是当目录则可以是:find . -name *.jpg 其中“.”表示当前目录,“*.jpg”是满足后缀为“.jpg”的所有文件。find命令是根据名称模糊条件进行搜索。
因为该工具是无损压缩,压缩比例不大,例如2.8M的图片压缩后是2.5M左右。