使用原始名称的部分文本重命名文件夹中的文件(批处理文件、powershell、其他解决方案)

Rename files in a folder using part of text of original name (batch file, powershell, other solution)

我有一个包含更多文件的文件夹需要重命名。

我需要将原名的一部分移到另一个位置。

文件名中的全部部分由“-”分隔(第一部分-第三部分-第二部分part.gif)

所有文件使用相同的结构。

我的原始文件:

111111111 - 333333333 - 2222222222.txt
AAAA AAA - CCC CCCC - BBB BBB.mp3
1home - 3home - 2home.jpg

期待结果:

111111111 - 2222222222 - 333333333.txt
AAAA AAA - BBB BBB - CCC CCCC.mp3
1home - 2home - 3home.jpg

所有文件名由三部分组成,我需要将第二部分与第三部分移动

扩展名不得更改,保留原扩展名。

任何脚本、软件都将不胜感激。

我尝试了这个 Powershell 代码,但似乎不起作用

Set-Location C:\pathHere\

Get-ChildItem | ForEach-Object {
    $artist,$album,$song = $_.BaseName.Split(" - ")
    Rename-Item $_ -NewName ($artist + " - " + $song + " - "  + $album + $_.Extension)
}

运行 您文件夹中的这个命令:

for /f "delims=-. tokens=1,2,3,4"   %i in ('dir /b') do echo rename "%i-%j-%k.%l" "%i-%k-%j.%l">> run-renames.bat

然后,将创建一个脚本文件运行-renames.bat

 rename "111111111 - 333333333 - 2222222222.txt" "111111111 - 2222222222- 333333333 .txt"
 rename "1home - 3home - 2home.jpg" "1home - 2home- 3home .jpg"
 rename "AAAA AAA - CCC CCCC - BBB BBB.mp3" "AAAA AAA - BBB BBB- CCC CCCC .mp3"

终于运行新脚本了。
注意:每次尝试后删除 运行-renames.bat,这样可以避免包含自身。

我选择将拆分后的文件名分配给一个数组。请注意,我使用的是 -Split。我强烈建议您打开一个 PS 会话并输入:get-help about_split。这将解释您对拆分输出的所有选择。

get-childitem | ForEach-Object { $arr = $_.BaseName -Split(' - ') ; Rename-Item $_ -NewName ($arr[0] + " - " + $arr[2] + " - "  + $arr[1] + $_.Extension) }

这是 运行 代码的输出。

PS C:\Powershell\rename\data> dir

    Directory: C:\Powershell\rename\data


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        2/26/2021   6:07 PM              0 111111111 - 333333333 - 2222222222.txt
-a----        2/26/2021   6:56 PM              0 1home - 3home - 2home.jpg
-a----        2/26/2021   6:56 PM              0 AAAA AAA - CCC CCCC - BBB BBB.mp3


PS C:\Powershell\rename\data> get-childitem | ForEach-Object { $arr = $_.BaseName -Split(' - ') ; Rename-Item $_ -NewName ($arr[0] + " - " + $arr[2] + " - "  + $arr[1] + $_.Extension) }
PS C:\Powershell\rename\data> dir


    Directory: C:\Powershell\rename\data


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        2/26/2021   6:07 PM              0 111111111 - 2222222222 - 333333333.txt
-a----        2/26/2021   6:56 PM              0 1home - 2home - 3home.jpg
-a----        2/26/2021   6:56 PM              0 AAAA AAA - BBB BBB - CCC CCCC.mp3


PS C:\Powershell\rename\data>

好吧,我真的不想回答 OP 在使用其标签时没有显示批处理文件编码工作的问题,但这里有一个可能的 解决方案:

@Echo Off&SetLocal EnableExtensions DisableDelayedExpansion
For %%G In ("* - * - *.*")Do (Set "BaseNameBefore=%%~nG"
    SetLocal EnableDelayedExpansion&For /F "Tokens=1-4 Delims=?" %%I In (
        "!BaseNameBefore: - =?!")Do EndLocal&If "%%L" == "" If Not %%K == "" (
        Ren "%%G" "%%I - %%K - %%J%%~xG"))

由于没有显示编码工作,我将让您自己分解代码的工作原理,无需我的解释。

使用 PowerShell,我会这样做:

(Get-ChildItem -Path 'D:\Test' -File -Filter '*-*-*.*') | 
    Rename-Item -NewName { $parts = ($_.BaseName -split '-').Trim()
                           '{0} - {1} - {2}{3}' -f $parts[0], $parts[2], $parts[1], $_.Extension
                         }

Get-ChildItem 连同开关 -File-Filter returns 文件的 FileInfo 对象数组,这些文件具有 3 'blocks' 由连字符分隔的文本 ( '*-*-*.*'), 所以我们可以确定这些名称可以分为三个部分。

然后通过管道将结果发送到 cmdlet Rename-Item,它可以在参数 -NewName 中获取脚本块。 在该脚本块内,只需将每个文件的 BaseName 拆分为其(已修剪)单独的部分,然后以不同的顺序将这些部分组合回去成为一个新的文件名。 (我喜欢对这样的事情使用 -f 格式运算符,因为它使代码非常易读)。

之前

D:\TEST
    111111111 - 333333333 - 2222222222.txt
    1home - 3home - 2home.jpg
    AAAA AAA - CCC CCCC - BBB BBB.mp3

之后

D:\TEST
    111111111 - 2222222222 - 333333333.txt
    1home - 2home - 3home.jpg
    AAAA AAA - BBB BBB - CCC CCCC.mp3

(Get-ChildItem -Path 'D:\Test' -File -Filter '*-*-*.*') 应该放在方括号之间的原因是,否则 Get-ChildItem cmdlet 可以在迭代文件夹时选取已经重命名的文件,从而多次重命名这些文件.
括号确保文件收集在通过管道发送之前完成。

注意 正如Squashman评论的那样,如果您确定拆分应该在Space Hyphen Space上完成,只需将-split '-'更改为-split ' - '