递归批量重命名

时间:2012-07-12 18:52:55

标签: macos batch-file rename

我有几个文件夹,其中包含一些我想从

重命名的文件
Foo'Bar - Title

Title

我正在使用OS X 10.7。我已经查看了其他解决方案,但没有一个能很好地解决递归问题。

有什么建议吗?

4 个答案:

答案 0 :(得分:7)

您的问题有两个部分:查找要递归操作的文件,然后重命名它们。

对于第一个,如果一切都在当前目录下面的一个级别,你可以只列出当前目录中每个目录的内容(如上面的Mattias Wadman的回答),但更一般地说(也可能更容易理解) ,要启动),您只需使用find命令。

对于第二个,你可以使用sed并找出如何正确引用引用和管道(你最终应该学习),但使用rename命令要简单得多。不幸的是,这个没有内置在Mac上,但您可以使用例如Homebrew安装它,或者只下载perl脚本和sudo install -m755 rename /usr/local/bin/rename

所以,你可以这样做:

find . -exec rename 's|[^/]* - ||' {} +

如果你想做一个“干跑”以确保它是正确的,添加“-n”标志重命名:

find . -exec rename -n 's|[^/]* - ||' {} +

要了解它是如何工作的,您真的应该阅读find的教程和重命名的联机帮助页,但要将其分解:

  • find .表示'在当前目录下递归查找所有文件'。
  • 您可以添加其他测试来过滤事物(例如,-type f如果您想跳过除常规文件之外的所有内容,或者`-name'* Title'如果您只想更改以'Title'结尾的文件),但这对您的使用没有必要。
  • -exec ... +表示批量处理找到的文件,并尽可能多地传递它们,以代替“...”中出现的命令中的任何{}
  • rename 's|[^/]* - ||' {}表示{}中的每个文件,将perl表达式s|[^/]* - ||应用于文件名,如果结果不同,则将其重命名为该结果。
  • s|[^/]* - ||表示匹配正则表达式“[^/]* -”并将匹配替换为''(空字符串)。
  • [^/]* -表示匹配任何以“ - ”结尾的非斜杠字符串。因此,在“./A/FooBar - Title”中,它会匹配“FooBar -”。

我应该提一下,当我有这么复杂的事情要做的时候,如果几分钟之后又有几次尝试用find / sed / awk / rename /等来做对,我仍然没有得到它我经常用Python和os.walk强制编写代码。如果您了解Python,那么您可能更容易理解(虽然更冗长,更简单),并且更容易修改为其他用例,所以如果您有兴趣,请提出。

答案 1 :(得分:3)

试试这个:

ls -1 * | while read f ; do mv "$f" "`echo $f | sed 's/^.* - //'`" ; done

我建议您在运行echo之前添加mv,以确保命令正常。正如abarnert在评论中指出的那样,这个命令一次只适用于一个目录。

各种命令的详细说明:

ls -1 *将为当前目录中的每个文件(和目录)输出一行(. - 文件除外)。因此,这将扩展到ls -1 file1 file2 ...-1ls告诉它只列出文件名和每行一个文件。

然后将输出传送到while read f ; ... ; done,这将在read f返回零时循环,直到它到达文件末尾为止。 read f一次从标准输入(在这种情况下是ls -1 ...的输出)读取一行,并将其存储在指定的变量中,在本例中为f

在while循环中,我们运行带有两个参数的mv命令,首先是"$f"作为源文件(注意用空格等处理文件名的引号),然后是使用sed的目标文件名和`(反引号)执行所谓的命令替换,它将在反引号中调用命令,并用标准输出的输出替换它。

echo $f | sed 's/^.* - //'将当前文件$f传输到sed中,该sed将匹配正则表达式并进行替换(s中的s/)并在标准输出上输出结果。正则表达式为^.* -,它将匹配字符串^的开头(称为锚点),然后匹配.*后跟-的任何字符,并将其替换为空字符串(//)之间的字符串。

答案 2 :(得分:1)

我知道您要求批量重命名,但我建议您use Automator。 它完美地运行,如果您将其创建为服务,您将在上下文菜单中选择:)

答案 3 :(得分:1)

经过一些反复试验,我遇到了这个解决同样问题的解决方案。

find <dir> -name *.<oldExt> -exec rename -S .<oldExt> .<newExt> {} \;

基本上,我利用了find和rename实用程序。这里的诀窍是找出将重命名放置在'{}'(表示需要通过重命名处理的文件)的位置。

P.S。重命名不是内置的linux实用程序。我使用OS X并使用自制软件来安装重命名。