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

重要步骤
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 }'`
    while [ "${zip_size}" -gt "${ZIP_MAX_SIZE}" ]
    do
        # 删除压缩包
        rm -rf "${ZIP_DIR}/${count}.zip"
        
        # 移回图片目录下一半的图片到解压目录
        half_num="$((${img_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)

格式:年-月-日 时:分:秒

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命令是根据名称模糊条件进行搜索。

猜你喜欢

转载自blog.csdn.net/qq_21084687/article/details/86518747