如何使用正则表达式批量重命名文件

如何使用正则表达式批量重命名文件

我的目录中有一堆文件夹,其中包含文件。大多数文件名都有区域代码(retropie),并且清理器不会匹配具有单字母区域代码(u、j、e 等)的 rom。我需要删除所有区域代码。区域代码全部包含在括号“ (...)”中。有没有办法删除所有括号及其之间的文本?

例如:

文件标题为

~/RetroPie/roms/<system>/

我想像这样重命名ROM:

Super Mario Bros (J).nes  
Super Random game (J,U,E).nes  

Super Mario Bros.nes  
Super Random game.nes

希望这能解决[暂停]标签的问题。

答案1

find . -iname '*.nes' | xargs -I {} rename -n 's/ *\(.*\)//g' "{}"

验证输出看起来不错,然后再次运行它而不使用 -n 以应用更改。

答案2

使用 Perlrename实用程序(如果可用)

find . -type f -name '* (*)*' -exec rename 's/ \([^)]*\)//g' {} +

这将找到当前目录中或当前目录下的所有常规文件,这些文件的名称中至少有一组匹配的括号。对于批量的此类文件,rename用于通过删除我们知道的括号(包括左括号之前的前导空格)来重命名文件。

如果你没有rename,那么...

假设您想要删除当前目录或以下目录中常规文件的所有名称中的所有括号,则find可以使用以下命令:

find . -type f -name '* (*)*' -exec bash -O extglob -c '
    for pathname do
        filename=${pathname##*/}
        mv -i "$pathname" "${pathname%/*}/${filename// (!(*\)*))}"
    done' bash {} +

这将找到文件名中带有括号的所有常规文件。对于批量的这些文件,bash将调用一个简短的脚本。

bash脚本将迭代当前一批找到的路径名,并且对于每个路径名,首先提取路径名的文件名部分,然后通过删除括号及其内容来重命名该文件。

代码中使用了三个参数替换。他们是

  1. ${pathname##*/}:这会从路径名中删除目录路径,只留下文件名。在本例中,它与 相同$(basename "$pathaname")

  2. ${pathname%/*}:这将从路径名中删除文件名并保留目录路径。在本例中,这与 相同$(dirname "$pathname")

  3. ${filename// (!(*\)*))}":这是一个bash特定的替换,从 的值中删除任何空格+括号$filename。子模式!(*\)*)是一个扩展的通配模式,它匹配任何不包含).我们使用它来删除各个括号,以便将诸如 之类的文件名0 (1) 2 (3) 转换为0 2而不仅仅是0.

如果有多个括号,所有这些都将被删除(如上所示)。

如果你确定你没有目录带有这样的括号,那么你可以使用更短的命令

find . -type f -name '* (*)*' -exec bash -O extglob -c '
    for pathname do
        mv -i "$pathname" "${pathname// (!(*\)*))}"
    done' bash {} +

测试第一个命令:

$ ls -l
total 0
-rw-r--r--  1 kk  wheel  0 Mar  6 18:21 Super Mario Bros (J).nes
-rw-r--r--  1 kk  wheel  0 Mar  6 18:21 Super Random game (J,U,E).nes
$ find . -type f -name '* (*)*' -exec prename 's/ \([^)]*\)//g' {} +
$ ls -l
total 0
-rw-r--r--  1 kk  wheel  0 Mar  6 18:21 Super Mario Bros.nes
-rw-r--r--  1 kk  wheel  0 Mar  6 18:21 Super Random game.nes

其他命令给出相同的结果。

相关内容