正则表达式批量重命名 OS X 终端中的文件

Posted

技术标签:

【中文标题】正则表达式批量重命名 OS X 终端中的文件【英文标题】:Regex to batch rename files in OS X Terminal 【发布时间】:2012-05-26 17:32:52 【问题描述】:

我正在寻找一种使用正则表达式批量重命名文件的方法,即

s/123/onetwothree/g

我记得我可以将 awk 和 sed 与正则表达式一起使用,但无法弄清楚如何将它们连接在一起以获得所需的输出。

【问题讨论】:

我只是想感谢 ccpizza,因为 Python 正则表达式脚本对我来说非常有用。我会投票,但我是菜鸟,所以不能......不能做太多......甚至不能发表评论。我在我的 MacBook Pro 上使用他的 Python 脚本来重命名带有捕获组的文件负载,因此我没有丢失任何重要信息,并且能够将文件名转换为更可接受的格式。我才刚刚开始使用 Python,但我喜欢正则表达式,而且这个脚本对我来说非常有用! 【参考方案1】:

您可以安装基于 perl 的重命名实用程序:

brew install rename

而不仅仅是像这样使用它:

rename 's/123/onetwothree/g' *

如果您想在不重命名任何文件的情况下测试您的正则表达式,只需添加 -n 开关

【讨论】:

【参考方案2】:

执行重命名操作的一种有效方法是在 sed 管道中构造重命名命令并将它们提供给 shell。

ls |
sed -n 's/\(.*\)\(123\)\(.*\)/mv "\1\2\3" "\1onetwothree\2"/p' |
sh

【讨论】:

onetwothree 之后的 \2 应该是 \3 唯一可以递归工作的东西(使用 find 命令)$ find . -iname test* | sed -E 's/\.\/(test)(.*)(\.jpg)/mv \1\2\3 \1\214\3/' | sh【参考方案3】:

我对一个友好的递归正则表达式文件名重命名器的看法,默认情况下只模拟替换并显示生成的文件名。

当您对试运行结果满意时,使用-w 实际写入更改,-s 禁止显示不匹配的文件; -h--help 将显示使用说明。

最简单的用法:

# replace all occurences of 'foo' with 'bar'
# "foo-foo.txt" >> "bar-bar.txt"
ren.py . 'foo' 'bar' -s

# only replace 'foo' at the beginning of the filename
# "foo-foo.txt" >> "bar-foo.txt"
ren.py . '^foo' 'bar' -s

也支持匹配组(例如\1\2 等):

# rename "spam.txt" to "spam-spam-spam.py"
ren.py . '(.+)\.txt' '\1-\1-\1.py' -s 

# rename "12-lovely-spam.txt" to "lovely-spam-12.txt"
# (assuming two digits at the beginning and a 3 character extension 
ren.py . '^(\d2)-(.+)\.(.3)' '\2-\1.\3' -s

注意:当您测试结果并想要实际编写更改时,不要忘记添加-w

适用于 Python 2.x 和 Python 3.x。

#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import print_function
import argparse
import os
import fnmatch
import sys
import shutil
import re


def rename_files(args):

    pattern_old = re.compile(args.search_for)

    for path, dirs, files in os.walk(os.path.abspath(args.root_folder)):

        for filename in fnmatch.filter(files, "*.*"):

            if pattern_old.findall(filename):
                new_name = pattern_old.sub(args.replace_with, filename)

                filepath_old = os.path.join(path, filename)
                filepath_new = os.path.join(path, new_name)

                if not new_name:
                    print('Replacement regex  returns empty value! Skipping'.format(args.replace_with))
                    continue

                print(new_name)

                if args.write_changes:
                    shutil.move(filepath_old, filepath_new)
            else:
                if not args.suppress_non_matching:
                    print('Name [] does not match search regex []'.format(filename, args.search_for))


if __name__ == '__main__':

    parser = argparse.ArgumentParser(description='Recursive file name renaming with regex support')

    parser.add_argument('root_folder',
                        help='Top folder for the replacement operation',
                        nargs='?',
                        action='store',
                        default='.')
    parser.add_argument('search_for',
                        help='string to search for',
                        action='store')
    parser.add_argument('replace_with',
                        help='string to replace with',
                        action='store')
    parser.add_argument('-w', '--write-changes',
                        action='store_true',
                        help='Write changes to files (otherwise just simulate the operation)',
                        default=False)
    parser.add_argument('-s', '--suppress-non-matching',
                        action='store_true',
                        help='Hide files that do not match',
                        default=False)

    args = parser.parse_args(sys.argv[1:])

    print(args)
    rename_files(args)

【讨论】:

谢谢@ccpizza。在 Windows 10 上使用 Python 3 效果很好。【参考方案4】:
files = "*"
for f in $files; do
     newname=`echo "$f" | sed 's/123/onetwothree/g'`
     mv "$f" "$newname"
done

【讨论】:

【参考方案5】:

Namechanger 超级好用。它支持用于搜索和替换的正则表达式:考虑我正在使用以下正则表达式进行超级复杂的重命名: \.sync-conflict-.*\. 那是一个救生员。

【讨论】:

是的.. 问题确实说终端......不过很有用! mrrsoftware.com/namechanger \.sync-conflict-.*\.这就是我要说的。也许使用 ls xargs 和 mv 我可以做类似的事情。这个应用程序是使整个操作系统值得运行的应用程序之一。一个真正的程序之美。

以上是关于正则表达式批量重命名 OS X 终端中的文件的主要内容,如果未能解决你的问题,请参考以下文章

linux下怎么批量重命名这些文件

百度云网盘批量改名之正则替换重命名

重命名 Unix 命令中的正则表达式

使用python批量修改文件名

使用 python 重命名文件 - 正则表达式

mac os x10.10批量重命名教程:os x 10.10批量修改文件名步骤