使用 find 和 sed 递归重命名文件

使用 find 和 sed 递归重命名文件

我想遍历一堆目录并将所有以 _test.rb 结尾的文件重命名为以 _spec.rb 结尾的文件。这是我从未弄清楚如何用 bash 来做的事情,所以这次我想花点力气把它搞定。不过到目前为止我还没有成功,我最大的努力是:

find spec -name "*_test.rb" -exec echo mv {} `echo {} | sed s/test/spec/` \;

注意:exec 之后有一个额外的回显,因此在我测试该命令时,会打印该命令而不是运行该命令。

当我运行它时,每个匹配的文件名的输出是:

mv original original

也就是说,sed 的替换已经丢失。有什么诀窍吗?

答案1

如果您没有rename(这是一个非常短的 Perl 脚本)或者您的重命名是更简单的 util-linux 版本,或者您只是想知道如何使您的命令工作:您只需将其发送到 shell 进行执行:

find spec -name "*_test.rb" -exec sh -c 'echo mv "$1" "$(echo "$1" | sed s/test.rb\$/spec.rb/)"' _ {} \;

答案2

太复杂了。如果您有rename可用的命令,您可以尝试以下命令:

find . -name "*_test.rb" -print0 | xargs -0 rename "s/_test/_spec/" 

这会找到相关文件,将它们发送到 xargs,然后 xargs 使用重命名工具(根据给定的 perl 正则表达式重命名文件)。

答案3

从 util-linux 重命名的手册页中:

   rename '_with_long_name' '' file_with_long_name.*

will remove the substring in the filenames.

因此,如果您没有 Perl 版本的 rename,此命令仍然有效:

find . -name "*_test.rb" -print0 | xargs -0 rename "_test..rb" "_spec/rb" 

相关内容