我有几个文件夹,其中包含一些我想从中重命名的文件
Foo'Bar - Title
到
Title
我正在使用 OS X 10.7。我看过其他解决方案,但没有一个能很好地解决递归问题。
有什么建议么?
我有几个文件夹,其中包含一些我想从中重命名的文件
Foo'Bar - Title
到
Title
我正在使用 OS X 10.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 的教程和 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,那么您可能会更容易理解(虽然更冗长且不那么简单),并且更容易修改为其他用例,所以如果您有兴趣,请询问。
试试这个:
ls -1 * | while read f ; do mv "$f" "`echo $f | sed 's/^.* - //'`" ; done
我建议您在运行之前添加一个echo
beforemv
以确保命令看起来没问题。正如 abarnert 在评论中指出的那样,此命令一次仅适用于一个目录。
各种命令的详细解释:
ls -1 *
将为当前目录中的每个文件(和目录)输出一行(.
-files 除外)。所以这将扩展为ls -1 file1 file2 ...
,-1
告诉ls
它只列出文件名和每行一个文件。
然后将输出通过管道传送到while read f ; ... ; done
which will loop whileread f
返回零,直到到达文件末尾。read f
从标准输入(在本例中为 的输出)一次读取一行ls -1 ...
并将其存储在指定的变量中,在本例中为f
.
在 while 循环中,我们运行一个mv
带有两个参数的命令,第一个"$f"
作为源文件(注意引号以处理带有空格等的文件名),第二个是目标文件名,它使用 sed 和 `(反引号)来执行所谓的命令替换,这将在反引号内调用命令并将其替换为标准输出的输出。
echo $f | sed 's/^.* - //'
将当前文件通过管道传输$f
到 sed 中,该文件将匹配正则表达式并进行替换(s
in s/
)并将结果输出到标准输出。正则表达式^.* -
将从字符串的开头匹配^
(称为锚定),然后匹配.*
后面的任何字符,-
并将其替换为空字符串(之间的字符串//
)。
我知道您要求批量重命名,但我建议您使用 Automator。它运行良好,如果您将其创建为服务,您将可以在上下文菜单中选择:)
经过反复试验,我遇到了这个解决方案,它可以帮助我解决同样的问题。
find <dir> -name *.<oldExt> -exec rename -S .<oldExt> .<newExt> {} \;
基本上,我利用了查找和重命名实用程序。这里的技巧是弄清楚rename的'{}'(表示需要通过rename处理的文件)放置在哪里。
PS rename 不是内置的 linux 实用程序。我使用 OS X 并使用自制软件安装重命名。