如何在Bash中比较忽略扩展名的文件名并清理目录重复文件
忽略扩展名对比文件名,删除dir2中的重复文件
没问题,我来帮你搞定这个需求——你之前的命令之所以失效,是因为它在对比完整的文件名(包括扩展名),而我们需要的是只对比文件名主体(去掉最后一个点及后面的扩展名部分)。下面给你几个实用的Bash实现方案,从直观到简洁都有:
方法一:直观的循环遍历(适合新手,易调试)
这个方法步骤清晰,方便你先验证要删除的文件,再执行真实删除:
# 第一步:收集dir1中所有文件的「无扩展名文件名」,存入临时文件 find "$dir1" -type f -exec basename {} \; | sed 's/\.[^.]*$//' | sort | uniq > /tmp/dir1_file_bases.txt # 第二步:遍历dir2中的每个文件,检查是否和dir1有重复的文件名主体 find "$dir2" -type f | while read -r target_file; do # 提取当前文件的文件名(不含路径) file_base=$(basename "$target_file") # 去掉扩展名,保留文件名主体(Bash参数扩展:%.* 表示删除最后一个.及后面的所有内容) name_no_ext="${file_base%.*}" # 精确匹配dir1的文件名主体,匹配到就标记删除 if grep -qxF "$name_no_ext" /tmp/dir1_file_bases.txt; then echo "准备删除重复文件:$target_file" # rm "$target_file" # 确认输出的文件都正确后,去掉注释执行真实删除 fi done # 第三步:清理临时文件 rm /tmp/dir1_file_bases.txt
关键细节:
${file_base%.*}:Bash原生的参数扩展,比sed更高效,能完美处理文件名里有多个点的情况(比如file.v2.txt会提取成file.v2)grep -qxF:-q静默匹配,-x整行精确匹配,-F把搜索内容当作纯文本(避免特殊字符干扰)
方法二:简洁的单行命令组合(适合熟练用户)
如果喜欢用管道组合命令,这个方案更紧凑,同样先验证再删除:
# 先收集dir1的无扩展名文件名 find "$dir1" -type f -exec basename {} \; | sed 's/\.[^.]*$//' | sort | uniq > /tmp/dir1_bases.txt # 一键匹配并删除dir2中的重复文件 find "$dir2" -type f -exec basename {} \; | awk -F. '{print $0 " " substr($0,1,length($0)-length($NF)-1)}' | grep -Ff /tmp/dir1_bases.txt | cut -d' ' -f1 | xargs -I {} echo "准备删除:$dir2/{}" # 确认后把echo改成rm:xargs -I {} rm "$dir2/{}" # 清理临时文件 rm /tmp/dir1_bases.txt
方法三:安全处理特殊文件名(含空格/换行符)
如果你的文件名里有空格、换行符或其他特殊字符,上面的方法可能出错,用这个null分隔的版本更可靠:
# 收集dir1的无扩展名文件名,用null字符分隔避免特殊字符干扰 find "$dir1" -type f -exec bash -c 'basename "$1" | sed "s/\.[^.]*$//"' _ {} \; | sort | uniq | tr '\n' '\0' > /tmp/dir1_bases_null.txt # 遍历dir2文件,安全处理特殊字符 find "$dir2" -type f -print0 | while IFS= read -r -d '' target_file; do file_base=$(basename "$target_file") name_no_ext="${file_base%.*}" if grep -qzxF "$name_no_ext" /tmp/dir1_bases_null.txt; then echo "准备删除:$target_file" # rm "$target_file" fi done rm /tmp/dir1_bases_null.txt
重要提醒:
无论用哪个方法,一定要先执行带echo的测试命令,确认要删除的文件都是你预期的重复文件,再去掉注释执行真实的rm操作,避免误删!
内容的提问来源于stack exchange,提问作者Kavintha Kulasingham
相关产品推荐
相关产品推荐

