我有很多 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
%
3A
5C
%
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