需要递归查找包含冒号的所有文件名并用破折号替换冒号?

Man*_*oke 2 linux terminal bash command-line

我有一个包含许多子目录的目录“main”,在其中一些子目录中,我的文件名包含冒号。我从 Linux 将“主”目录上传到了 GitHub 存储库,但是当我尝试从 Windows 机器上的这个存储库中提取时遇到了问题,因为 Windows 不允许文件名中有冒号。

如何使用 Linux 终端在“主”目录中递归查找所有带冒号的文件名,然后用一个破折号 (-) 字符替换冒号?

Kam*_*ski 5

find /path/to/directory -type f -name "*:*" -exec rename -n 's/:/-/g' {} +
Run Code Online (Sandbox Code Playgroud)

(如果此命令对您不起作用,请参阅本答案末尾的兼容性说明。)

这是一个基本的安全版本,只打印会发生什么。为了让它真正发生,摆脱-n选项。

没有它也可以工作,-name "*:*"但最好find只传递应该更改的文件名,因为这会使整个命令更快。

它是这样工作的:

  • find 发现...
    • ...在/path/to/directory目录...
    • ...所有文件 ( -type f)...
    • ...具有匹配的名称 ( -name "*:*"),...
    • ...然后执行rename(如果需要多次)...
    • ......与更换模式:-...
    • ...在找到的所有文件上,一次多个文件 ( {} +)。

笔记:

  • 该命令不会重命名目录,这是设计使然。
  • 重命名可能不适用于文件名中的一些异常字符(例如换行符)。可以肯定的是,您在那里没有这样的文件名,因此这是一个正式的注释。

兼容性说明

该解决方案采用Perl脚本renamerenameDebian的,Ubuntu的可用包。其他发行版可能rename来自util-linux.

本手册建议非 Perl 的解决方案rename应该是:

find /path/to/directory -type f -name "*:*" -execdir rename -n ':' '-' {} +
Run Code Online (Sandbox Code Playgroud)

(同样,-n如果看起来正确,请删除。)不过我还没有测试过。我认为它只会替换文件名中的第一个冒号。解决方法是重复该命令(不带-n,带-v),直到没有冒号为止。

或者,您可以从该站点上可用的存档中获取 Perl 脚本(目前File-Rename-0.20.tar.gz,该脚本名为rename.PL)。另请参阅此问题