You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何配置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

火山引擎 最新活动