2

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

Foo'Bar - Title

Title

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

有什么建议么?

4

4 回答 4

8

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

首先,如果所有内容都在当前目录的下一级,您可以只列出当前目录中每个目录的内容(如上面 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 的教程和 rename 的联机帮助页,但将其分解:

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

我应该提一下,当我有一些复杂的事情要做这样的事情时,如果几分钟后尝试使用 find/sed/awk/rename/etc. 把它弄好,我仍然没有得到它,我经常只需使用 Python 和 os.walk 进行命令式编码即可。如果您了解 Python,那么您可能会更容易理解(虽然更冗长且不那么简单),并且更容易修改为其他用例,所以如果您有兴趣,请询问。

于 2012-07-12T21:02:53.960 回答
3

试试这个:

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

我建议您在运行之前添加一个echobeforemv以确保命令看起来没问题。正如 abarnert 在评论中指出的那样,此命令一次仅适用于一个目录。

各种命令的详细解释:

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

然后将输出通过管道传送到while read f ; ... ; donewhich will loop whileread f返回零,直到到达文件末尾。read f从标准输入(在本例中为 的输出)一次读取一行ls -1 ...并将其存储在指定的变量中,在本例中为f.

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

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

于 2012-07-12T19:11:29.423 回答
2

我知道您要求批量重命名,但我建议您使用 Automator。它运行良好,如果您将其创建为服务,您将可以在上下文菜单中选择:)

于 2013-04-10T19:18:38.040 回答
1

经过反复试验,我遇到了这个解决方案,它可以帮助我解决同样的问题。

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

基本上,我利用了查找和重命名实用程序。这里的技巧是弄清楚rename的'{}'(表示需要通过rename处理的文件)放置在哪里。

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

于 2017-08-21T05:45:28.120 回答