Linux如何删除仅扩展名大小写不同的同名文件中更早的版本?
Linux下批量删除仅扩展名大小写不同的旧文件解决方案
完全可以实现,通过Shell脚本结合系统内置的文件属性查询命令即可完成需求
核心思路
- 按「主文件名 + 小写扩展名」对所有文件分组,同一组内的文件就是仅扩展名大小写不同的同名文件
- 对每组内的文件,对比存储时间(可选择修改时间或创建时间)
- 保留组内时间最新的文件,删除其余更早的文件
重要提醒:操作前请先备份所有相关文件,或先执行测试脚本确认待删除文件符合预期,避免误删数据。
步骤1:执行测试脚本(仅输出待删文件,不执行删除)
将以下代码保存为dry_run.sh,放在需要处理的文件目录下运行:
#!/bin/bash # 声明关联数组存储分组信息 declare -A latest_mtime declare -A latest_filename # 遍历当前目录下所有带扩展名的文件 for file in *.*; do # 跳过目录,仅处理普通文件 [ -f "$file" ] || continue # 拆分主文件名和扩展名 base_name="${file%.*}" ext_name="${file##*.}" # 生成分组标识:主文件名+小写扩展名,保证仅大小写不同的扩展名分到同一组 group_key="${base_name}_${ext_name,,}" # 获取当前文件的修改时间戳(秒级,要对比创建时间则把%Y换成%W,仅支持ext4/xfs/btrfs等带birth time的文件系统) current_time=$(stat -c %Y "$file") # 分组不存在或当前文件时间更新,更新分组的最新文件信息 if [ -z "${latest_mtime[$group_key]}" ] || [ "$current_time" -gt "${latest_mtime[$group_key]}" ]; then if [ -n "${latest_filename[$group_key]}" ]; then echo "待删除:${latest_filename[$group_key]} (晚于它的同组文件:$file)" fi latest_mtime[$group_key]="$current_time" latest_filename[$group_key]="$file" else # 当前文件时间更早,标记为待删 echo "待删除:$file (晚于它的同组文件:${latest_filename[$group_key]})" fi done
运行方式:
chmod +x dry_run.sh ./dry_run.sh
核对输出的待删除文件列表,确认完全符合你的预期后再执行下一步。
步骤2:执行实际删除脚本
确认待删列表无误后,把dry_run.sh中所有echo "待删除:xxx"的行替换为rm -f命令即可,修改后的核心代码片段如下:
# 替换前的echo行 # echo "待删除:${latest_filename[$group_key]} (晚于它的同组文件:$file)" # 替换为 rm -f "${latest_filename[$group_key]}" # 另一处echo行 # echo "待删除:$file (晚于它的同组文件:${latest_filename[$group_key]})" # 替换为 rm -f "$file"
修改完成后再次运行脚本即可执行删除操作。
可选调整项
- 如需处理子目录下的所有文件,将
for file in *.*替换为find . -type f -name "*.*" | while read -r file即可,可自动处理带空格的文件名 - 如需按主文件名分组(不管扩展名是什么,只要主名相同就归为一组),将
group_key的生成规则改为group_key="${base_name,,}"即可
内容的提问来源于stack exchange,提问作者Johsttin Curahua
相关产品推荐
相关产品推荐

