如何批量复制/移动不同文件夹中的同名文件并避免覆盖?
解决同名文件批量复制/移动不覆盖的问题
我完全懂你的困扰——460个文件夹里的snps.vcf直接复制肯定会互相覆盖,关键是要给每个文件加上唯一标识,比如它原所在的文件夹名称,这样就能完美避免冲突了。下面给你几个实用的解决方案:
方法1:用find结合Shell命令重命名复制
这个方法适合不管文件夹嵌套多深的情况,会把文件的原路径转换成合法的文件名部分:
find . -type f -name "snps.vcf" -exec sh -c 'cp "$0" "/home/AWAN/try/$(dirname "$0" | tr / _)_snps.vcf"' {} \;
- 解释:
dirname "$0"会获取当前文件所在的文件夹路径,tr / _把路径里的斜杠/换成下划线_(避免文件名包含非法字符),最后拼接成新文件名。比如./project/folder1/snps.vcf会变成project_folder1_snps.vcf,绝对不会重复。
方法2:用循环批量处理(更直观)
如果所有目标文件夹都是当前目录的一级子目录,这个方法更简单易懂:
for file in */snps.vcf; do # 获取当前文件所在的文件夹名称 folder_name=$(basename "$(dirname "$file")") # 复制并重命名 cp "$file" "/home/AWAN/try/${folder_name}_snps.vcf" done
- 效果:比如
folderA/snps.vcf会被复制为folderA_snps.vcf,每个文件名对应原文件夹,清晰好辨认。
方法3:用xargs配合文本处理重命名
如果你习惯用管道命令,也可以这么写:
find . -type f -name "snps.vcf" | xargs -I {} sh -c 'new_name=$(echo "{}" | tr / _); cp {} "/home/AWAN/try/$new_name"'
- 效果:原路径
./subdir/folderX/snps.vcf会变成_subdir_folderX_snps.vcf,同样保证唯一性。
补充说明
- 如果要移动文件而不是复制,把命令里的
cp换成mv就行; - 执行前可以先把
cp换成echo cp,预览一下生成的新文件名是否符合预期,没问题再去掉echo执行实际操作。
内容的提问来源于stack exchange,提问作者Furqan




