我有一堆带有嵌套目录的子目录,其中包含具有以下名称的文件
output.txt
。我想将所有这些文件重命名为
output_modified.txt
我试过
find . -type f -name "output.txt" -execdir rename 's/output\.txt/output_modified\.txt/' '{}' \;
但它给出了错误
rename: not enough arguments
我缺少什么论点或者有更好的方法来做我需要的事情吗?
答案1
你不需要rename
这里,只需这样做:
find . -name output.txt -type f -execdir mv -T output.txt output_modified.txt ';'
这-T
是一个 GNU 扩展。如果没有它,如果已经存在名为 的目录,则mv output.txt output_modified.txt
可以重命名output.txt
为。output_modified.txt/output.txt
output_modified.txt
这里rename
可能很有用,因为它可以一次重命名多个文件,因此可以使其比mv
每个文件调用一个更有效,但您需要:
到确保你的
rename
是基于 perl 的之一,不是 中的那个傻瓜util-linux
。有时也称为file-rename
或prename
或perl-rename
。将其调用为:
find . -name output.txt -type f -exec rename ' s|\.txt\z|_modified.txt|' {} +
通过这种{} +
形式,find
一次传递多个到rename
。
基于 perl 的某些变体rename
还可以使用文件列表来重命名标准输入上的 NULL 分隔符,因此使用这些文件,您还可以执行以下操作:
find . -name output.txt -type f -print0 |
rename -0 's|\.txt\z|_modified.txt|'
答案2
IMO 重命名、查找等操作令人困惑且难以使用。我发现这种事情更容易使用mv
,https://github.com/sharkdp/fd和 GNU 并行。
fd output.txt | parallel --dry-run mv {} {.}_modified.txt
parallel
运行您为输入的每一行输入的命令(在本例中将fd
给出路径列表)。{}
意思是“当前输入”。{.}
表示当前输入,但删除了扩展名。--dry-run
只会打印将要运行的命令parallel
,而不会看到它们。您应该先运行它,然后在--dry-run
您满意后运行它。
您必须从包管理器安装 fd 和 parallel。