我有一个巨大的文件树。有些文件具有相同的名称,但大小写不同,例如some_code.c
和Some_Code.c
。
因此,当我尝试将其复制到 NTFS/FAT 文件系统时,它会询问我是否要替换该文件或跳过该文件。
有没有办法自动重命名此类文件,例如,通过添加 (1)
冲突文件的名称(如 Windows 7 那样)?
答案1
许多 GNU 工具(例如cp
、mv
和 )tar
支持在目标存在时创建备份文件。也就是说,当复制foo
到 时bar
,如果已经有一个名为 的文件bar
,则现存的 bar
将被重命名,并且复制后将bar
包含foo
.默认情况下,bar
被重命名为bar~
,但可以修改行为:
# If a file foo exists in the target, then…
cp -r --backup source target # rename foo → foo~
cp -r --backup=t source target # rename foo → foo.~1~ (or foo.~2~, etc)
还有其他变体,例如仅在备份已存在时才创建编号备份。请参阅coreutils手册更多细节。
答案2
我试过
apropos copy | grep "(1)"
为了寻找可能的候选人,mcopy 出现了。
man mcopy
显示了一个有前途的选择-D clash-option
不是很酷吗?但没那么酷——没有描述。但是mtools.dvi有一些提示,我在我的系统上搜索,没有成功,通过google搜索,没有成功,但是后来,用google,我直接搜索mcopy clash-option
并找到了这个网站。
我做了一个简短的测试
mcopy -D A f* a
测试 autorename 和 targetdir a
- 它不是自动重命名,而是要求我忽略或覆盖每个文件,那个愚蠢的...。
我的版本是mtools-4.0.10
1996 年 - 15 岁的帮助页面。与此同时,我们真的应该失去一些功能吗?
我会把工作分成两步:
- 创建一个简短的函数,如果该名称已被占用,它会为文件生成一个唯一的名称。
- 运行
find
,并为您要复制的每个文件执行该脚本。
我们应该协助这种方法吗? :)
这是一个自动重命名文件的脚本:
#!/bin/bash
name=$1
target=$2
autorename () {
name=$1
target=$2
no=$3
test -e ${target}/${name}.$no && autorename ${name} ${target} $((no+1)) || cp ${name} ${target}/${name}.$no
}
test -e ${target}/${name} && autorename ${name} ${target} 0 || cp ${name} ${target}
这是我的测试调用:
find -maxdepth 1 -name "fo*" -type f -exec ./autorename.sh {} /mnt/hidden/test/a ";"
注意:-maxdepth、-name 和 -type 用于显着限制受影响文件的数量。我没有测试脚本的更深层次的文件结构,也没有测试文件名中的空格和其他时髦的字符,如换行符、分页符等。
我使用 .1 是因为它在大多数命令中不会造成麻烦,而 a ( 和 a ) 通常需要屏蔽。
答案3
cp
至少,不适用于 GNU 。
强烈建议您不要使用重复的文件名(忽略大小写),它们只会给您带来痛苦。使用查找此类重复项的列表
find . | tr A-Z a-z | sort | uniq -d
然后手动重命名每一行的文件之一(如果输出)。尽量避免将来创建重复项。