复制、重命名和移动目录中的所有文件

Copy, rename and move all files in directory

我有很多 pdf 文件需要复制、重命名和移动。
复制和移动有效——我只是不知道重命名部分是如何完成的。

文件如下所示:

2021-05-05_10-10-12-609_Testperson_Nancy_2512489996_19490816_OD_20210429112706.pdf  
2021-06-05_11-11-12-135_Testperson_with_many _Names_0708681234_19490817_OD_20210429112715.pdf  

我需要将它们重命名为:

251248-9996_19490816_OD_20210429112706.pdf  
070868-1234_19490817_OD_20210429112715.pdf  

因此需要从右起第四个 _(没有第一个 _)进行子串,在 [6] 和 [7] 之间添加一个 -

这是我目前得到的:

SET input=c:\temp\rename\input
SET backup=c:\temp\rename\backup
SET output=c:\temp\rename\output

if not exist "%backup%" mkdir "%backup%"
for /f "tokens=*" %%F IN ('DIR /S /B "%input%\*.pdf"') DO (
xcopy /-y "%%F" "%backup%" & move "%%F" "%output%"
)

c:\temp\rename\input (对于原始文件) c:\temp\rename\backup (原始文件的备份目录) c:\temp\rename\output (重命名文件)

这必须 运行 作为 Windows 服务器上的计划批处理文件作业(我知道如何 运行 该作业)

试一试。我建议您先备份您的文件,然后 运行 在您的生产文件中这样做:

@echo off & setlocal enabledelayedexpansion
set "input=c:\temp\rename\input"
set "backup=c:\temp\rename\backup"
set "output=c:\temp\rename\output"
mkdir "%backup%">nul 2>&1
for /f "delims=" %%i in ('dir /b /s /a-d "%input%\*.pdf"') do (
    set "cnt=-4"
    set "_tmp=%%~i"
    set "_tmp=!_tmp: =-!
    set "_strip=!_tmp:_= !"
    for %%c in (!_strip!) do (
    set /a cnt+=1
 )
    if !cnt! gtr 1 if defined _tmp call :parser !cnt! "%%i"
)
goto :eof
:parser
for /f "tokens=%~1,* delims=_" %%a in ("%~2") do set "fin=%%~b"
echo xcopy /-y "%~2" "%backup%"
echo move "%~2" "%output%\%fin:~0,6%-%fin:~6%"

一些注意事项。这确实 而不是 但会执行实际的 copymove,作为安全措施,它只会 echo 结果。所以一旦你看到它做了它应该做的,那么你可以从最后两行中删除 echo

最后,这是假设您提供的文件格式,但它确实适合空格和双 _ 但如果您有另一个 _ 分隔部分,它会向南不构成标准格式的一部分。

演示 鉴于您在问题和评论中给出的 4 个示例(我示例中的 C:\tmp\Input 除外,因为我使用不同的目录进行测试):

您可能可以使用 PowerShell 更轻松地完成此操作,但为了切题,这里有一个 which gets some assistance from

@Echo Off
SetLocal EnableExtensions
Set "input=C:\temp\rename\input"
Set "backup=C:\temp\rename\backup"
Set "output=C:\temp\rename\output"
For /F "Tokens=1-2 Delims=|" %%G In (
    '%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile
     "Get-ChildItem -LiteralPath '%input%' -Filter '*_*_*_*_*.pdf' -File | "
     "ForEach-Object { $_.FullName + '|' + "
     "(($_.Name).Split('_')[-4]).Insert(6,'-') + '_' + "
     "(($_.Name).Split('_')[-3..-1] -Join('_')) }"') Do (
    Echo=%SystemRoot%\System32\xcopy.exe "%%G" "%backup%\" && (
        Echo=Move /Y "%%G" "%output%\%%H"))
Pause

目前,该脚本只会向您显示它将要执行的命令 运行,如果您对输出满意,请从第 12 行和 13 行中删除 Echo= ] 和可选的最后一行。作为旁注,我为 目标使用了尾部反斜杠,这将导致创建 %backup%,如果它尚不存在的话。