You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:编写按指定大小分类文件的Shell脚本

嘿,你的思路方向没问题,但确实用ls -l提取文件大小是个容易踩坑的做法——毕竟ls的输出是给人读的,格式可能随系统、locale甚至终端设置变化,碰到带空格、换行符或者特殊字符的文件名时,用cut之类的工具解析绝对会出问题。给你两个更可靠的实现方案:

推荐实现方案

1. 用stat命令写Shell脚本(兼容bash/zsh)

stat是专门用来获取文件元数据的工具,能精准拿到文件大小,完全不受文件名特殊字符影响。不同系统的stat参数略有区别,下面是跨平台的完整示例脚本:

#!/bin/bash

# 检查输入参数是否正确
if [ $# -ne 2 ]; then
    echo "用法: $0 <目标目录路径> <大小阈值(字节)>"
    exit 1
fi

TARGET_DIR="$1"
THRESHOLD="$2"

# 创建用于存放分类文件的子目录(-p参数确保父目录不存在时也能创建)
LARGE_DIR="$TARGET_DIR/larger_than_$THRESHOLD"
SMALL_DIR="$TARGET_DIR/smaller_than_$THRESHOLD"
mkdir -p "$LARGE_DIR" "$SMALL_DIR"

# 遍历目标目录下的所有条目,只处理普通文件
for file in "$TARGET_DIR"/*; do
    if [ -f "$file" ]; then
        # 获取文件大小:Linux用stat -c "%s",macOS用stat -f "%z"
        if command -v stat >/dev/null 2>&1; then
            if [[ "$OSTYPE" == "darwin"* ]]; then
                FILE_SIZE=$(stat -f "%z" "$file")
            else
                FILE_SIZE=$(stat -c "%s" "$file")
            fi
        else
            echo "错误:系统未安装stat命令"
            exit 1
        fi

        # 比较大小并移动文件
        if [ "$FILE_SIZE" -gt "$THRESHOLD" ]; then
            mv "$file" "$LARGE_DIR/"
        elif [ "$FILE_SIZE" -lt "$THRESHOLD" ]; then
            mv "$file" "$SMALL_DIR/"
        fi
        # 注:这里没有处理等于阈值的文件,你可以根据需求添加对应的逻辑
    fi
done

echo "文件分类完成!大于$THRESHOLD字节的文件存放在$LARGE_DIR,小于的存放在$SMALL_DIR"

2. 用find命令快速实现(更简洁)

find自带文件大小筛选功能,一行命令就能搞定批量移动,不需要手动遍历:

#!/bin/bash

if [ $# -ne 2 ]; then
    echo "用法: $0 <目标目录路径> <大小阈值(字节)>"
    exit 1
fi

TARGET_DIR="$1"
THRESHOLD="$2"

LARGE_DIR="$TARGET_DIR/larger_than_$THRESHOLD"
SMALL_DIR="$TARGET_DIR/smaller_than_$THRESHOLD"
mkdir -p "$LARGE_DIR" "$SMALL_DIR"

# 移动大于阈值的文件(+后面的数字加c表示字节,换成k就是KB,M就是MB)
find "$TARGET_DIR" -maxdepth 1 -type f -size +"$THRESHOLD"c -exec mv {} "$LARGE_DIR" \;

# 移动小于阈值的文件
find "$TARGET_DIR" -maxdepth 1 -type f -size -"$THRESHOLD"c -exec mv {} "$SMALL_DIR" \;

echo "分类完成!"

这里的-maxdepth 1确保只处理目标目录下的文件,不会递归到子目录里,符合你的需求。

为什么不推荐用ls -l?

主要有两个硬伤:

  • 输出格式不稳定:不同系统、不同语言环境下,ls -l的列位置或显示格式可能变化,虽然大部分默认第5列是文件大小,但风险始终存在。
  • 特殊文件名解析失败:如果文件名包含空格、换行符或者特殊符号,ls的输出会被拆分成多个字段,用cut -d' ' -f5提取的内容完全错误,甚至导致脚本执行异常。

最后补充个小细节:如果需要处理隐藏文件(比如.gitignore这类),在bash里可以先执行shopt -s dotglob开启显示隐藏文件的选项,这样遍历的时候就能包含它们了。

内容的提问来源于stack exchange,提问作者Arnau Martínez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:24:16