Linux中如何对find+ls命令输出的月年日期列按时间排序
解决方案
问题原因
你原来的命令存在两个核心问题:
- 仅按第6列(月份字符串)排序,sort默认不会自动识别月份顺序,仅按字母排序会出现10月(Oct)排在12月(Dec)之前的逻辑错误
- ls默认对半年内的文件输出时间、超过半年的文件输出年份,导致第8列存在年份和时间两种格式,排序逻辑完全混乱
方案1:最简修改(改动最小,输出格式和原格式完全一致)
sudo find / -maxdepth 4 -size +1M -exec ls -lh --time-style=+'%b %d %Y' {} \; | sort -k 8,8nr -k 6,6Mr -k 7,7nr
参数说明:
--time-style=+'%b %d %Y':强制ls的日期统一输出为「月份缩写 日期 四位年份」格式,不管文件新旧都不会出现时间,避免列格式不一致- sort参数逻辑:
-k 8,8nr:优先按第8列(年份)倒序排序,按数字识别,最新年份在前-k 6,6Mr:次优先按第6列(月份缩写)倒序排序,-M参数会自动识别月份顺序,12月>11月>…>1月-k 7,7nr:最后按第7列(日期)倒序排序,按数字识别,月内日期大的在前
如果需要正序(最旧的文件在前),只需要去掉所有参数末尾的r即可。如果需要精确到时间排序,可把时间格式调整为%b %d %Y %H:%M,再对应增加sort的时间列排序规则即可。
方案2:高效批量处理(适合文件数量多的场景)
当搜索的文件量很大时,-exec ls会为每个文件单独启动ls进程,效率较低,可以用find直接输出时间戳排序后再格式化:
sudo find / -maxdepth 4 -size +1M -printf "%T@ %s %p\n" | sort -k1,1nr | awk ' BEGIN { split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", m, " ") } { ts = $1; size = $2; path = substr($0, length($1)+length($2)+3) # 转换时间为指定格式 cmd = "date -d @" ts " +\"%b %d %Y\"" cmd | getline d; close(cmd) # 转换大小为可读格式 u = "BKMGT"; i=0 while (size >= 1024 && i < 4) { size /= 1024; i++ } size_s = sprintf("%.1f%s", size, substr(u,i+1,1)) # 输出格式可按需调整 printf "%-8s %s %s\n", size_s, d, path }'
内容的提问来源于stack exchange,提问作者cber11
相关产品推荐
相关产品推荐

