30

试图重命名一堆文件。

我可以在当前目录中使用 bar 重命名 foo 的任何实例:

ls . | awk '{print("mv "$1" "$1)}' | sed 's/foo/bar/2' | /bin/sh

我可以添加什么使其递归?

编辑/我的解决方案

我不知道/理解这种 shell 类型的东西,所以我用一些(很脏的)Ruby 做了它:

5.times do
  Dir["**/*"].each do |f|
    file_name = File.absolute_path f
    should_rename = file_name.include? "yolo"
    new_file_name = file_name.gsub("yolo", "#{@project_name}")
    File.rename(f, new_file_name) if (should_rename and File.exists? f)
  end
end
4

5 回答 5

66

有人问过这个问题:递归批量重命名

以您的示例为例,您可以使用:

brew install rename
find . -exec rename 's|foo|bar|' {} +
于 2013-06-05T08:45:48.180 回答
20

rename实用程序还提供了一种不需要正则表达式知识的语法。安装实用程序后

brew install rename

该选项将替换by-s的第一个实例:foobar

find . -exec rename -s 'foo' 'bar' {} +

该选项-S将替换所有实例:

find . -exec rename -S '_' ' ' {} +

这实际上与Marcel Steinbach上面提供的解决方案相同,只是语法不同。

于 2016-10-18T12:44:14.137 回答
8

此网页(存档版本)的干净,零依赖(所以没有brew install rename或其他) 。

例如,在这个示例案例中,我从.jsto切换.ts到将项目从 vanilla javascript 移动到 typescript,因此我想首先将所有内容从 *.js 重命名为 *.ts。

find . -iname "*.js" -exec bash -c 'mv "$0" "${0%\.js}.ts"' {} \;

瞧。

要记住的唯一技巧是您有两个“之前”前缀点和一个“之后”。也就是说,在我的情况下,您.js需要更改两个实例。一个查找.js文件,然后另一个将其替换.js.ts.

find . -iname "*.js" -exec bash -c 'mv "$0" "${0%\.js}.ts"' {} \;
   first before ^                   second before ^   ^ one after
于 2020-09-24T20:55:50.197 回答
2

“我如何在某些文件结构上递归地执行 X”的答案几乎总是使用find. 在这种情况下,也可能与for循环结合使用。以下示例将递归循环匹配foo当前目录中的模式的文件。

thedir=./
for file in $(find $dir -type f -name foo); do
    # rename $file here
done

根据您所需的重命名方案以及您希望如何表达重命名,循环体将具有不同的重命名命令。

简单地重命名每个名为footo的文件bar将产生一个文件bar,这不是人们通常想要的。该$file变量包含文件的相对路径,因此 differentsbar将具有不同的路径。

于 2013-06-05T08:40:16.357 回答
2

您还可以使用 Finder 递归地重命名文件。

  1. 浏览到需要重命名的项目树所在的文件夹。
  2. 将 Finder 窗口切换到“列表”视图。
  3. 展开所有子文件夹。这可以使用键盘快捷键完成:⌘-A(Cmd-A,全选),→(右箭头键,展开文件夹)。
  4. 重复 ⌘-A、→ 命令,直到打开所有子文件夹并选择所有文件。
  5. 右键单击所选文件之一,然后选择“重命名 xx 项...”
  6. 使用打开的“重命名 Finder 项目:”面板根据需要替换、添加或格式化文本。
  7. 点击“重命名”
于 2020-04-13T19:25:23.980 回答