如何有条件地重命名或覆盖文件副本?

时间:2018-06-14 15:32:26

标签: batch-file

我需要一个.bat文件来复制假脱机打印目录中的所有文件,然后将它们粘贴到桌面上的output文件夹中。我已经拥有的东西:

@echo off & setlocal
mkdir "%userprofile%\Desktop\"%date:/=-%" 
del /f /s /q "C:\Windows\System32\spool\PRINTERS\*.*" >nul 2>nul
rem Group all file names by size
for /R %%a in (%userprofile%\Desktop\"%date:/=-%"\*.spl) do call set size[%%~Za]=%%size[%%~Za]%%,"%%~Fa"
rem Process groups
for /F "tokens=2* delims=[]=," %%a in ('set size[') do Call :Sub %%a %%b
Goto :Eof
:Sub
If "%~3"=="" (Set "size[%1]="&goto :EOf)
processing %*
Keep %2
Shift&shift
:loop
Del  %1
"C:\Windows\System32\spool\PRINTERS\*.spl" "%userprofile%\Desktop\%date:/=-%" >nul 2>nul
if not "%~2"=="" (shift&goto :loop)

我希望.bat文件能够将文件连续复制到output文件夹,如果文件名相同,则按大小检查差异,如果是,请复制到output文件夹。如果文件未被更改,则删除它。但是当我运行它时,没有任何反应。有什么问题?

.bat文件必须连续运行,等待打印机在假脱机目录中创建文件。如果存在,.bat文件应检测到它并复制到output文件夹。但问题是打印机将生成具有相同名称和扩展名的另一个文件。 .bat需要将其复制到output文件夹(但由于它具有相同的名称,因此.bat文件需要先重命名。)

因此,如果文件已存在名称005.spl(在output文件夹中)且另一个文件(大小相同)的名称相同,则.bat文件必须将其复制并传递到output文件夹,例如005(1).spl。这是我不知道该怎么做。

1 个答案:

答案 0 :(得分:1)

@echo off & setlocal

rem Get 1st argument. Undefined spool to disable Delete SPL Mode.
set "spool=%~1"

rem If cmdline argument passed, do delete mode else do copy mode.
if defined spool (
    echo Delete SPL Mode
    echo.
    set "func=DeleteSpl"
    if not exist "%spool%\*.spl" (
        >&2 echo No spl files found.
        exit /b 1
    )
    set "output="
    rem Optional pause so you can manually exit the console if wanted.
    rem pause
) else (
    echo Copy SPL Mode
    echo.
    set "spool=%systemroot%\System32\spool\PRINTERS"
    set "output=%userprofile%\Desktop\%date:/=-%"
    set "func=CopySpl"
)

rem Timeout for loop cycle.
set "sleeptime=1"

rem Make output folder.
if defined output if not exist "%output%" mkdir "%output%"

:loop
setlocal

rem Group all file names by size.
for /R "%spool%" %%a in (*.spl) do call set size[%%~Za]=%%size[%%~Za]%%,"%%~Fa"

rem Check size[ is valid.
2>nul >nul set size[|| (
    endlocal
    >nul timeout /t %sleeptime% /nobreak
    goto :loop
)

rem Process groups.
for /F "tokens=2* delims=[]=," %%a in ('set size[') do call :%func% %%a %%b

endlocal

rem Avoid looping for delete mode.
if "%func%" == "DeleteSpl" exit /b 0

>nul timeout /t %sleeptime% /nobreak
goto :loop

exit /b 0


rem Copy spl files from spool to output.
:CopySpl
    setlocal

    rem Skip 1st argument.
    set "skip1="

    for %%a in (%*) do (
        if not defined skip1 (
            set "skip1=1"
        ) else (
            call :SaveAs "%%~a" "%output%\%%~NXa"
        )
    )
exit /b 0


rem Renames to output with an index number.
:SaveAs
    setlocal
    set "pathname=%~DPN2"
    set "name=%~N2"
    set "i=0"

    rem Check size with all files in output folder.
    for %%a in ("%output%\*.spl") do if "%~Z1" == "%%~Za" exit /b 0

    :NewNameLoop
    set /a "i+=1"
    if exist "%pathname%(%i%).spl" goto :NewNameLoop

    rem Copy with indexed name to output.
    echo Keep: "%~NX1" as "%name%(%i%).spl"  %~Z1
    copy "%~1" "%pathname%(%i%).spl" >nul 2>nul
exit /b 0


rem Delete spl in output based on size.
:DeleteSpl
    setlocal

    rem Skip 1st and 2nd argument.
    set "skip1="
    set "skip2="

    for %%a in (%*) do (
        if not defined skip1 (
            set "skip1=1"
        ) else if not defined skip2 (
            set "skip2=1"
        ) else (
            echo Delete: "%%~NXa"
            del "%%~a"
        )
    )
exit /b 0

此代码将假脱机文件复制到输出文件夹。 如果没有假脱机文件,则退出errorlevel 1。

:CopySpl标签的调用将skip1设置为未定义。第一圈 将skip1检测为未定义,并将其设置为1以便跟随 循环将通过这个未定义的条件。

所有文件都将重命名为copy,并带有索引编号。

假脱机文件夹可能设置了某些权限,请考虑这一点 当你运行脚本时。

使用循环让copy永远保持下去。超时sleeptime为1秒。

使用索引号将:SaveAs标签调用copyfilename(index).spl

该脚本还接受输出文件夹的参数以删除文件 具有相同大小,即按大小删除重复项。这个模式呢 不要使用无限循环。