如何按文件名中的日期排序ls输出,保留最新3个文件并删除其余?
解决方案:按文件名日期排序并保留最新3个文件
为什么不推荐用ls file_*处理?
ls的输出在文件名包含空格、换行等特殊字符时会出现解析错误,且依赖ls的排序逻辑不够灵活,直接用bash的glob匹配和数组操作是更安全可靠的方式。
具体实现步骤
- 将目标文件存入数组
直接通过bash的通配符匹配,把所有符合file_*格式的文件存入数组,避免ls的潜在问题:
files=(file_*)
- 按日期部分降序排序
由于你的文件名日期部分是固定格式的14位数字(YYYYMMDDHHMMSS),数字越大代表时间越新。可以通过两种方式排序:
- 方式一:直接对文件名反向字符串排序(因日期格式固定,字符串排序结果和数字排序一致)
IFS=$'\n' sorted_files=($(printf "%s\n" "${files[@]}" | sort -r))
- 方式二:精准提取日期字段排序(更严谨,即使文件名含其他
_也能正确识别日期部分)
IFS=$'\n' sorted_files=($(printf "%s\n" "${files[@]}" | sort -t '_' -k2,2nr))
解释:-t '_'指定分隔符为_,-k2,2nr表示按第2个字段(即日期部分)进行数字降序排序。
- 保留最新3个,删除其余文件
先判断文件总数是否超过3,若超过则删除第4个及以后的文件:
if (( ${#sorted_files[@]} > 3 )); then # 提取需要删除的文件(数组从0开始索引,第4个元素对应索引3) to_delete=("${sorted_files[@]:3}") # 用空字符分隔文件名,避免特殊字符导致的删除错误 printf "%s\0" "${to_delete[@]}" | xargs -0 rm -f fi
完整脚本示例
#!/bin/bash # 匹配目标文件存入数组 files=(file_*) # 如果没有匹配到文件,直接退出 [[ ${#files[@]} -eq 0 ]] && exit 0 # 按日期字段降序排序 IFS=$'\n' sorted_files=($(printf "%s\n" "${files[@]}" | sort -t '_' -k2,2nr)) # 删除多余文件 if (( ${#sorted_files[@]} > 3 )); then to_delete=("${sorted_files[@]:3}") printf "%s\0" "${to_delete[@]}" | xargs -0 rm -f echo "已删除文件:${to_delete[*]}" else echo "文件数量不超过3,无需删除" fi
内容的提问来源于stack exchange,提问作者user971741
相关产品推荐
相关产品推荐

