perl `rename` 脚本在某些情况下不起作用?

perl `rename` 脚本在某些情况下不起作用?

我尝试运行以下命令:

find . -type f -exec rename -v 's/ /_/g' {} \;

,以递归方式重命名所有文件,名称中包含空格和下划线。问题是它有时有效,有时无效。当它不起作用时,我收到以下错误:

Can't rename ./dir/subdir/file name with spaces ./dir/subdir/file_name_with_spaces: No such file or directory

我可能做错了什么吗?

答案1

发生的情况是您尝试rename在以下文件上运行目录名称中带有空格。默认情况下,该rename实用程序有点简单化,它将给定的 Perl 代码位应用于完整的参数,即完整的路径名,而不仅仅是路径名的文件名部分。

幸运的是,很容易将操作限制为路径名的文件名部分:

find . -type f -execdir rename -v 'tr/ /_/' -- {} \;

-execdir谓词是非标准的,但普遍实现。使用-execdirin 代替-exec,这会使用找到文件的目录作为当前目录来执行命令。这样,rename实用程序永远看不到文件的父目录的名称。

我在这里使用--它来防止我们尝试重命名名称以破折号开头的文件的事件(请参阅“--”(双破折号)是什么意思?)。这对于 GNU 来说不是问题,find因为文件名将以 为前缀,但至少在 BSD 系统./的某些实现上不会发生这种情况。find

另一种选择是使用该rename实用程序的-d--filename--nopath--nofullpath选项(这些都是相同的):

find . -type f -exec rename -d -v 'tr/ /_/' {} +

这会阻止实用程序考虑任何给定路径名参数的文件名部分以外的任何内容。

我冒昧地将 Perl 表达式从一个s///命令更改为一个tr///命令,因为我们正在执行的转换是一个简单的音译,而不是通用替换。

您可能还希望仅对rename包含空格的文件名运行。-name '* *'-exec或之前通过测试选出这些-execdir

相关内容