【问题标题】:I need a command line to rename files to a pattern我需要一个命令行将文件重命名为模式
【发布时间】:2018-01-05 19:50:55
【问题描述】:

我使用媒体转换工具将一些视频转换为 MP3。不幸的是,该工具不遵循命名约定,我找不到文件名选项。

特别是,它去掉了艺术家和标题之间的连字符。所以

Smash Mouth - All Star.mp4

变成

Smash Mouth   All Star.mp3

有大约 2600 个文件需要转换,所以我宁愿将所有转换完成到一个文件夹中,然后我可以运行批处理文件或命令。我尝试了类似

ren "*   *.mp3" "*. - *.mp3"

但它没有效果(没有引号,它会产生一个错误,并且使用问号而不是 *,据我了解,就字长而言,文件名需要一个固定的模式)。

有什么想法吗?我已经安装了 PowerShell,但从未使用过它,所以如果这是要走的路,请指点我一些文档的方向(我之前被引导到的 PowerShell 源现在是一个断开的链接)。

[编辑]

我将从这里的建议开始,看看是否可以根据我的目的对其进行修改。

https://superuser.com/questions/1230586/renaming-files-with-a-standard-pattern-as-and-when-they-are-added-to-a-folder

【问题讨论】:

    标签: powershell batch-file command-line


    【解决方案1】:

    这是一个批处理文件解决方案。批处理文件应保存在包含该目录或其子目录中所有 *.mp3 文件的目录中,并通过双击执行。

    @echo off
    for /F "eol=| delims=" %%I in ('dir "*   *.mp3" /A-D /B /S 2^>nul') do call :RenameFile "%%I"
    set "NewName="
    pause
    goto :EOF
    
    :RenameFile
    set "NewName=%~nx1"
    set "NewName=%NewName:   = - %"
    ren "%~1" "%NewName%"
    goto :EOF
    

    命令DIR搜索

    • 仅用于文件,因为/A-D(不是属性目录)
    • 在当前目录和所有子目录中因为/S
    • 对于包含 3 个连续空格的 *.mp3 文件和
    • 由于/B 找到的文件的名称带有文件扩展名和完整路径,因此以裸格式输出。

    DIR 命令行由 FOR 在后台的单独命令进程中执行,该命令进程捕获此命令进程的输出(= command DIR) 编写用于处理 STDOUT

    DIR 在整个目录树中未找到任何匹配通配符模式以处理 STDERR 的文件时可能输出的错误通过使用 2>nul 将其重定向到设备来抑制NUL。另请阅读有关 Using Command Redirection Operators 的 Microsoft 文章,了解对 2>nul 的解释。当 Windows 命令解释器在执行命令 FOR 在后台启动的单独命令进程中执行嵌入的dir 命令行。

    FOR 命令处理从 DIR 的输出中捕获的每一行。 FOR 忽略以 ; 开头的行的默认行为被选项 eol=| 禁用。字符 | 不能用于文件/文件夹名称,因此不能位于文件名或文件路径的开头。 FOR 将水平制表符和空格上的每一行拆分为子字符串的默认行为被选项 delims= 指定一个空的分隔符列表禁用。所以 FOR 确实将每个文件名与完整路径和文件扩展名分配给循环变量I

    注意: eol=| 在这里不是必需的,因为带有选项 /SDIR 会逐行输出带有完整路径的文件名,这使得FOR 处理的行以分号开头。但是文件名可以以分号开头,尽管这对于不使用 DIR 选项 /S 以获取 *.mp3 文件列表而以艺术家和标题为名称的 *.mp3 文件不太可能在没有路径的当前目录中。

    重要的是在捕获的文件名列表上运行 FOR,而不是让 FOR 自己递归搜索 MP3 文件,否则它可能会在文件期间发生重命名某些 MP3 文件会因为循环迭代期间的目录条目更改而被跳过。

    对于每个文件名,调用子程序RenameFile,将完整的文件名作为第一个用双引号括起来的参数传递给子程序。双引号对于处理文件名或文件路径中包含空格或其中一个字符 &()[]{}^=;!'+,`~ 的文件名也是必需的。

    使用子例程而不是直接在 FOR 循环中执行剩余代码,因为这将需要使用延迟的环境变量扩展,如果已处理文件的文件/文件夹名称包含可能出现一个或多个感叹号。

    在子程序RenameFile中,当前文件的名称没有路径被分配给环境变量NewName

    接下来对文件名应用字符串替换,以用空格、连字符、空格替换所有连续出现的三个空格。因此,此代码不能 100% 保证连字符实际上是插入艺术家部分和标题部分之间而不是空格,因为没有脚本代码没有访问包含艺术家和标题的大型数据库能够确定什么是艺术家和什么是每个文件名中的标题部分。

    然后执行文件重命名,并按照命令REN的要求,指定要重命名的文件用完整路径和文件扩展名不带路径的新名称。

    命令 ECHO 可以插入到ren 以首先运行批处理文件,以检查文件重命名是否会按预期完成。

    要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

    • call /?
    • dir /?
    • echo /?
    • for /?
    • goto /?
    • pause /?
    • ren /?
    • set /?

    另见Where does GOTO :EOF return to?

    【讨论】:

      【解决方案2】:

      如果你想走 Powershell 路线,你可以使用 Get-ChildItem 和 Rename-Item 命令以及正则表达式。

      例如

      Get-ChildItem -Path C:\path\to\your\folder | foreach{ Rename-Item -NewName { $_.Name -replace '\[.*\]' }
      

      这里还有一篇关于使用带正则表达式的 PS 的帖子:

      Use Regex / Powershell to rename files

      希望有帮助!

      【讨论】:

      • 这绝对让我开始使用 PowerShell。谢谢!
      【解决方案3】:

      编辑: 由于您提到使用 Batch/CMD,您可以使用以下内容。

      @echo off
      
      for /f "tokens=*" %%i in ('dir \path\to\files /B /A-D') DO (
              set var=%%i
              set var=%var:   = - %
              ren \path\to\"%%~i" "%var%"
      )
      

      现在,这是因为您显示文件名包含三个空格和省略的破折号。只需更改您的路径,确保您以适当的权限运行脚本以更改文件名。

      PowerShell 方式如上所述:

      gci \path\to\files|%{rni {$_.Name -replace '\[.*\]'}}
      

      【讨论】:

      • 谢谢。我没有使用任何包含 `! 的文件名对其进行测试,所以这是有道理的。我编辑了我的解决方案以反映您的更改。
      • 但是如果没有延迟扩展,现在发布的批处理文件解决方案根本不起作用。命令行中的%var% set var=%var: = - %ren \path\to\"%%~i" "%var%" 在执行 FOR 之前已经由 Windows 命令解释器处理/扩展。以这种方式无法执行此文件重命名任务。可以在set var=%%i 之后执行setlocal EnableDelayedExpansion 并在REN 命令之后插入endlocal,并使用延迟扩展(即使用感叹号)在var 之间进行引用。
      • 这显然需要一些调整。一旦我更正了路径并将其保存到 .bat 并运行它,我得到了一个重命名和三个“存在重复文件名”(在目标文件夹中的四个文件上)。一个重命名的文件以- = - 或类似名称结束,没有扩展名。
      • 上面的 PowerShell 方法缺少一个右括号,但它让我开始使用 PowerShell,所以这很重要。 Mofi 发布的已编辑批处理文件现在可以使用,所以我暂时将使用它。在查找 PowerShell 文档时,我遇到了一个监视输出文件夹更改的脚本,因此我将把它合并到我最终的 PS 脚本中。
      猜你喜欢
      • 1970-01-01
      • 2013-08-27
      • 2012-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 2015-04-14
      • 2016-02-26
      相关资源
      最近更新 更多