使用 xargs 重命名多个文件而不使用循环

0 bash xargs

我有一个包含文件的文件夹

a1.cpp
a2.cpp
a3.cpp
a4.cpp
a5.cpp
a6.cpp
Run Code Online (Sandbox Code Playgroud)

我希望将 2 到 5 范围内的文件扩展名更改为 .java

如何在不使用循环的情况下在 xargs 的帮助下重命名这些文件?

最终输出将是

a1.cpp
a2.java
a3.java
a4.java
a5.java
a6.cpp
Run Code Online (Sandbox Code Playgroud)

Adm*_*Bee 5

与往常一样,在使用xargs文件名时,如果文件名包含重要字符,则必须小心。

也就是说,假设您有 GNU 版本的findxargs以及-print0-0选项,则可以执行以下操作:

find . -type f -name 'a[2-5].cpp' -print0 | xargs -0 rename 's/cpp$/java/'
Run Code Online (Sandbox Code Playgroud)

这将用于find根据您的要求生成相关文件的列表,并将它们输出为以 NULL 结尾的字符串,以确保正确处理带有空格等的文件名。然后,xargs使用相应的-0选项来调用(外部)rename工具,您可以向该工具提供sed样式名称转换命令(请注意,这假设基于 Perl 的rename工具,而不是 util-linux 变体,如 @ilkkachu 所指出的 - 请参阅在这里进行讨论)。

我不知道这是否可以称为使用的“有效方法” xargs,但从您的评论中我认为您想探索xargs 的可能性,这是一种相当可靠的方法。您描述的任务可以完全通过使用 shell 语法功能来完成,而无需xargs完全使用该rename命令,如下所示:

rename 's/cpp$/java/' a[2-5].cpp
Run Code Online (Sandbox Code Playgroud)

如果您没有 Perl 版本rename,但有util-linux变体,则相应的命令是

rename ".cpp" ".java" a[2-5].cpp
Run Code Online (Sandbox Code Playgroud)

但是,由于缺少正则表达式样式锚点,这将用替换来替换第一次出现的原始模式。在这种情况下,任务是更改文件后缀,这不太可能成为问题,因为.cpp只会在名称末尾出现一次,但在一般情况下,在制定命令时必须小心。