如何配置zip命令仅对压缩率≥20%的文件启用Deflate压缩(适配低功耗CPU解压场景)
如何配置zip命令仅对压缩率≥20%的文件启用Deflate压缩(适配低功耗CPU解压场景)
嗨,我完全懂你的需求——给低功耗CPU准备的压缩包,绝对不想为了那1%、2%的压缩率浪费解压时的CPU资源,只给真正能压到20%以上的文件用Deflate压缩,剩下的直接存储对吧?咱们一步步来解决这个问题,分两种方案:用Mac自带的原生zip命令(写个小脚本实现),或者用更灵活的第三方工具。
方案一:用Mac原生Info-ZIP 3.0实现(脚本定制)
遗憾的是,原生的zip命令没有直接设置「压缩率阈值」的参数,不过我们可以写个shell脚本,先对每个文件单独测试压缩效果,再决定用压缩模式还是存储模式添加到最终的zip包。
具体脚本示例
把下面的代码保存成smart-zip.sh,然后给它加执行权限(chmod +x smart-zip.sh),运行就行:
#!/bin/bash # 配置参数,根据你的需求修改 TARGET_ZIP="GravityExpress.pdx.zip" SOURCE_DIR="./GravityExpress.pdx" MIN_COMPRESSION_RATIO=20 # 要求至少压缩20%才启用Deflate # 先清理已存在的目标zip包 rm -f "$TARGET_ZIP" # 遍历所有需要打包的文件(跳过目录) find "$SOURCE_DIR" -type f | while read -r FILE; do # 获取原文件大小 ORIG_SIZE=$(stat -f "%z" "$FILE") if [ "$ORIG_SIZE" -eq 0 ]; then # 空文件直接用存储模式添加 zip -0 "$TARGET_ZIP" "$FILE" >/dev/null 2>&1 echo "处理 $FILE:空文件,直接存储" continue fi # 创建临时zip测试压缩效果 TEMP_ZIP=$(mktemp) zip -q "$TEMP_ZIP" "$FILE" # 提取该文件在临时zip中的压缩后大小 COMPRESSED_SIZE=$(unzip -l "$TEMP_ZIP" | awk '/[0-9] +'"$(basename "$FILE")"'/ {print $1}') rm -f "$TEMP_ZIP" # 计算压缩率(百分比) COMPRESSION_PERCENT=$(( 100 - (COMPRESSED_SIZE * 100 / ORIG_SIZE) )) echo "处理 $FILE:压缩率 $COMPRESSION_PERCENT%" if [ "$COMPRESSION_PERCENT" -ge "$MIN_COMPRESSION_RATIO" ]; then # 满足压缩率要求,用默认Deflate压缩添加 zip "$TARGET_ZIP" "$FILE" >/dev/null 2>&1 else # 不满足,用存储模式(无压缩)添加 zip -0 "$TARGET_ZIP" "$FILE" >/dev/null 2>&1 fi done # 单独添加目录结构(find遍历文件不会包含空目录,需要手动处理) find "$SOURCE_DIR" -type d | while read -r DIR; do # 先删除可能重复的目录条目,再添加 zip -d "$TARGET_ZIP" "$DIR/" 2>/dev/null zip -0 "$TARGET_ZIP" "$DIR/" >/dev/null 2>&1 done echo "完成!已生成符合要求的压缩包:$TARGET_ZIP"
脚本说明
- 脚本会先测试每个文件的压缩效果,计算压缩率,只有当压缩率≥20%时才用Deflate压缩,否则直接存储
- 自动处理空文件和目录结构,保证zip包的目录完整性
- 运行时会输出每个文件的处理状态,方便你验证
注意事项
- 这个脚本会比直接用
zip -r慢一些,因为每个文件都要单独测试压缩效果,但换来的是完全符合你的需求 - 如果需要调整压缩率阈值,修改
MIN_COMPRESSION_RATIO的值就行
方案二:用第三方工具p7zip(更灵活高效)
如果你愿意安装免费工具,p7zip(7-Zip的Mac版本)是个不错的选择,它的压缩效率更高,而且我们可以用类似的脚本思路实现,或者结合它的参数优化。
步骤1:安装p7zip
打开终端,用Homebrew安装:
brew install p7zip
步骤2:定制脚本(类似原生zip的思路)
其实和上面的脚本逻辑差不多,只是把zip命令换成7z命令,测试压缩的方式稍微调整:
#!/bin/bash TARGET_ZIP="GravityExpress.pdx.7z" # 7z格式,也可以改成.zip SOURCE_DIR="./GravityExpress.pdx" MIN_COMPRESSION_RATIO=20 rm -f "$TARGET_ZIP" find "$SOURCE_DIR" -type f | while read -r FILE; do ORIG_SIZE=$(stat -f "%z" "$FILE") if [ "$ORIG_SIZE" -eq 0 ]; then 7z a -mx0 "$TARGET_ZIP" "$FILE" >/dev/null 2>&1 echo "处理 $FILE:空文件,直接存储" continue fi TEMP_ZIP=$(mktemp) 7z a -mx5 -q "$TEMP_ZIP" "$FILE" COMPRESSED_SIZE=$(7z l "$TEMP_ZIP" | awk '/[0-9]+ [0-9]+ +'"$(basename "$FILE")"'/ {print $2}') rm -f "$TEMP_ZIP" COMPRESSION_PERCENT=$(( 100 - (COMPRESSED_SIZE * 100 / ORIG_SIZE) )) echo "处理 $FILE:压缩率 $COMPRESSION_PERCENT%" if [ "$COMPRESSION_PERCENT" -ge "$MIN_COMPRESSION_RATIO" ]; then 7z a -mx5 "$TARGET_ZIP" "$FILE" >/dev/null 2>&1 else 7z a -mx0 "$TARGET_ZIP" "$FILE" >/dev/null 2>&1 fi done # 添加目录 find "$SOURCE_DIR" -type d | while read -r DIR; do 7z d "$TARGET_ZIP" "$DIR/" 2>/dev/null 7z a -mx0 "$TARGET_ZIP" "$DIR/" >/dev/null 2>&1 done echo "完成!已生成压缩包:$TARGET_ZIP"
mx5是7-Zip的中等压缩级别,你可以改成mx9(最高压缩)或者mx1(快速压缩),根据你的需求调整- 7-Zip的压缩速度和效率通常比原生zip更好,适合处理大量文件
额外小提示
你给出的示例中,像mp3、部分pdv文件的压缩率只有1%-2%,这些文件本身已经是压缩格式了,Deflate确实压不出多少空间,反而会增加解压负担,用存储模式完全没问题;而json、bin这类文件压缩率很高,用Deflate能省不少空间,也不会给低功耗CPU带来太多解压压力。
备注:内容来源于stack exchange,提问作者Nino van Hooff




