如何批量重命名以 % 作为分隔符的 Windows 文件?

如何批量重命名以 % 作为分隔符的 Windows 文件?

我有很多 Windows 文件,其中文件名包含 %。见下文:

c:\temp>
dir /b
114902_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1489879.pdf
114904_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1489880.pdf
114906_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1491058.pdf
114916_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1491059.pdf
114918_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1491452.pdf
114920_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1491453.pdf
114923_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1491454.pdf
115513_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039292647.pdf
115515_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039295860.pdf
115517_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039296218.pdf
115523_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039308592.pdf
115525_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039308593.pdf
120342_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039328905.pdf
120345_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039337204.pdf
120348_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039337221.pdf
120351_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039337461.pdf
120639_T%3A%5CAccounting%5CPayables%5CAPA%5CAFA MAY 15%5CINV#63168731.pdf
120640_T%3A%5CAccounting%5CPayables%5CAPA%5CAFA MAY 15%5CINV#63168988.pdf
120642_T%3A%5CAccounting%5CPayables%5CAPA%5CAFA MAY 15%5CINV#63168993.pdf
120644_T%3A%5CAccounting%5CPayables%5CAPA%5CAFA MAY 15%5CINV#63169027.pdf

这些 % 实际上是 : (%3A) 和 \ (%5C) 的十六进制代码。我无法解释它们从其他系统复制过来后是如何变成这样的,但这就是我必须处理的。为了清楚起见,这是十六进制代码的样子。

114902_T:\Accounting\Payables\APA\Boshart Apr 25\BII_inv_1489879.pdf

我想要做的是从此重命名文件:

114902_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1489879.pdf

更改为:

BII_inv_1489879.pdf

我尝试按照其他重命名示例使用 % 作为分隔符,但使事情变得更加复杂的是,最后一个分隔符(pdf 文件名)并不总是第 7 个标记。

任何帮助都将不胜感激。

答案1

如果你正在Windows 10,你应该学习和使用 电源外壳用于管理和自动化。它非常强大而且很有趣。

根据你的样本名称和期望结果,我选择拆分'%5C' 并使用索引 -1,无论长度如何,它都会获取数组中的最后一个元素。

详细:

$path = 'c:\temp'
Get-ChildItem $path | Rename-Item -NewName { ($_ -split '%5C')[-1] }

在控制台:

gci c:\temp | ren -NewName { ($_ -split '%5C')[-1] }

获取子项

重命名项目

关于分裂

字符串操作演示:

PS C:\...\keith>$oldnames
114902_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1489879.pdf
114904_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1489880.pdf
114906_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1491058.pdf
114916_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1491059.pdf
114918_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1491452.pdf
114920_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1491453.pdf
114923_T%3A%5CAccounting%5CPayables%5CAPA%5CBoshart Apr 25%5CBII_inv_1491454.pdf
115513_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039292647.pdf
115515_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039295860.pdf
115517_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039296218.pdf
115523_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039308592.pdf
115525_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039308593.pdf
120342_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039328905.pdf
120345_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039337204.pdf
120348_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039337221.pdf
120351_T%3A%5CAccounting%5CPayables%5CAPA%5CABB MAY 15%5C0039337461.pdf
120639_T%3A%5CAccounting%5CPayables%5CAPA%5CAFA MAY 15%5CINV#63168731.pdf
120640_T%3A%5CAccounting%5CPayables%5CAPA%5CAFA MAY 15%5CINV#63168988.pdf
120642_T%3A%5CAccounting%5CPayables%5CAPA%5CAFA MAY 15%5CINV#63168993.pdf
120644_T%3A%5CAccounting%5CPayables%5CAPA%5CAFA MAY 15%5CINV#63169027.pdf
PS C:\...\keith>$oldnames | ForEach{ ($_ -split '%5C')[-1] }
BII_inv_1489879.pdf
BII_inv_1489880.pdf
BII_inv_1491058.pdf
BII_inv_1491059.pdf
BII_inv_1491452.pdf
BII_inv_1491453.pdf
BII_inv_1491454.pdf
0039292647.pdf
0039295860.pdf
0039296218.pdf
0039308592.pdf
0039308593.pdf
0039328905.pdf
0039337204.pdf
0039337221.pdf
0039337461.pdf
INV#63168731.pdf
INV#63168988.pdf
INV#63168993.pdf
INV#63169027.pdf

答案2

我将编写一个 PowerShell 脚本,迭代文件名并使用以下内容重写它们:

$dir = Get-ChildItem -Path "PUTFULLPATHHERETODIRECTORY"
foreach($P in $dir) {
    Rename-Item -path $P -newname $P.FullName.Substring($P.FullName.lastindexof("%5C")+3)
}

首先,我们获取目标文件夹的内容。然后,对于目录中的每个项目,将其重命名为从“%5C”模式的最后一个索引开始的名称,并添加 3 个空格以将其删除。

当然,把完整路径放在我放的位置放置FULLPATHHERETODIRECTOR

答案3

使用*5c作为分隔符,并通过获取目标名称子字符串set命令,这将获取文件名的最后一部分,而不必担心它是否是标记 5、6、7 等,因为它总是获取最后一个分隔符后的字符串......

根据分隔符将字符串拆分为子字符串,作者:Sponge Belly / DosTips.com

set "_trick=%_name:*5c=" & set "_name=%"

@echo off && setlocal enabledelayedexpansion

for %%i in (*.pdf)do call :_ren_: "%%~ni" && ren "%%~fi" "!_name!%%~xi"

:_ren_:
set "_name=%~1" <nul || endlocal && goto :EOF
set "_trick_=%_name:*5c=" & set "_name=%" && exit /b 
  • Powershell 中也一样
gci C:\temp\*.pdf|Ren -New {$_ -replace '.*%5C',''}

在此处输入图片描述

答案4

以下是命令提示符(批处理)解决方案,带有变体。(我将问题解释为删除所有内容(包括) 最后的 %nn序列.pdf,然后将文件重命名为该序列。)

@echo off
setlocal enabledelayedexpansion
for %%F in (*.pdf) do (
    set file=%%F
    call :process
)
goto :eof

:process
    set temp=%file%
    :find_all
    REM Remove everything through first %.
    set right=!temp:*%%=!
    REM If there's no change, there were no %'s.
    if not "%right%" == "%temp%" (
        REM Remove the two characters after the %.
        set temp=%right:~2%
        goto :find_all
    )
    if "%file%" == "%right%" (
        REM Filename didn't contain %.
        echo File %file% is unchanged.
    ) else if "%right:~4%" == "" (
        REM Name was abcd%5C.pdf (or abcd%.pdf), so there's nothing left.
        echo Nothing left after truncating %file%
    ) else if exist "%right%" (
        REM The "ren" command will give an error message for this,
        REM but it doesn't say the filename.
        echo Cannot rename %file% because %right% already exists.
    ) else (
        echo ren "%file%" "%right%"
    )
    goto :eof

总体方法是获取每个文件名并删除第一个序列中的所有内容(包括),然后重复此操作直到没有剩余内容。我们将几个技巧整合在一起。%nn

  • 我们使用语法来编辑文件名。%var:str1=str2%
  • 我们使用以下形式来删除/替换所有内容(包括)第一次出现的 %var:*str1=str2%str1
  • 我们使用setlocal enabledelayedexpansion,不是因为我们需要延迟扩展本身, 但我们可以使用进行替换 ,所以我们可以使用!var:str1=str2!%str1
  • 像往常一样,当我们想要%在批处理文件中使用时,我们必须键入 %%

因此,该语句set right=!temp:*%%=!将 设置为第一个 之后(右侧) right 的部分。这将是一个可能以或开头的字符串 (因为这些是示例文件名中后面出现的十六进制字符)。然后我们去掉这两个字符并将结果赋值回 。temp%3A5C%temp

运行上述命令并检查输出。如​​果看起来没问题,则更改为,echo ren这样ren它实际上就会重命名文件。


如果要求删除最后一个%5C 而不是最后一个的所有内容,请使用以下命令:%nn

@echo off
setlocal enabledelayedexpansion
for %%F in (*.pdf) do (
    set file=%%F
    call :process
)
goto :eof

:process
    set temp=%file%
    :find_all
    REM Remove everything through first %5C.
    set right=!temp:*%%5C=!
    REM If there's no change, there were no %5C's.
    if not "%right%" == "%temp%" (
        set temp=%right%
        goto :find_all
    )
    if "%file%" == "%right%" (
        REM Filename didn't contain %5C.
        echo File %file% is unchanged.
    ) else if "%right:~4%" == "" (
        REM Filename was abcdef%5C.pdf, so there's nothing left.
        echo Nothing left after truncating %file%
    ) else if exist "%right%" (
        REM The "ren" command will give an error message for this,
        REM but it doesn't say the filename.
        echo Cannot rename %file% because %right% already exists.
    ) else (
        echo ren "%file%" "%right%"
    )
    goto :eof

其他说明:

  • 这些已经在 Windows 7 上测试过。
  • 原则上,这些可以通过一个简单的循环来完成for,迭代文件。但是 for 当我使用时循环中断goto,所以我不得不将辅助循环移到子程序中。
  • 我通常会将信息作为参数传递到子程序中。但当文件名包含时,此方法失败 %
  • 这些例程会进行适量的错误检查。
  • 它们处理任意数量的(或 )序列。%nn%5C
  • 它们处理任意数量的空格,包括最后一个序列之后的空格(即在新文件名中)。%nn

相关内容