我想遍历一堆目录并将所有以 _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"