我有一个包含文件的文件夹
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)
与往常一样,在使用xargs文件名时,如果文件名包含重要字符,则必须小心。
也就是说,假设您有 GNU 版本的find和xargs以及-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只会在名称末尾出现一次,但在一般情况下,在制定命令时必须小心。