批处理文件将文件向上移动一级重命名重复项

时间:2018-04-08 19:26:54

标签: batch-file duplicates move renaming

我一直在尝试创建一个批处理文件,我可以将其放入MAIN FOLDER目录并运行它将所有* .EXT分别向上移动到Folder2和Folder3中的一个级别:

C:\Main Folder\Folder2\Folder3a\File1.EXT
C:\Main Folder\Folder2\Folder3b\File2.EXT
C:\Main Folder\Folder2\Folder3c\File3.EXT
C:\Main Folder\Folder2\Folder3d\File1.EXT
C:\Main Folder\Folder3\Folder3a\File1.EXT
C:\Main Folder\Folder3\Folder3b\File2.EXT
C:\Main Folder\Folder3\Folder3c\File3.EXT
C:\Main Folder\Folder3\Folder3d\File1.EXT

问题是在Folder2和Folder3子文件夹中都存在重复文件:File1.EXT 我在这里发现的将文件向上移动一级的所有内容总是会覆盖重复项 我找到的用于重命名重复项的解决方案并未与移动文件的解决方案“合并”。

有人能建议更简单的方法吗?

2 个答案:

答案 0 :(得分:0)

@echo off
setlocal

if "%~1" == "test" call :test

for /d /r %%F in (*) do (
    for /d %%G in ("%%F\*") do (
        for %%H in ("%%~G\*.EXT") do (
            call :move "%%~H" "%%~F"
        )
    )
)
exit /b

:move
setlocal

if /i not exist "%~2\%~nx1" (
    echo 1. move "%~1" "%~2"
    move "%~1" "%~2"
    exit /b
)

set "name=%~n1"

for /l %%I in (1 1 9) do (
    if "%name:~-4%" == " (%%I)" (
        set "name=%name:~0,-4%"
    )
)

for /l %%I in (1 1 9) do (
    if not exist "%~2\%name% (%%I)%~x1" (
        echo 2. move "%~1" "%~2\%name% (%%I)%~x1"
        move "%~1" "%~2\%name% (%%I)%~x1"
        exit /b
    )
)
exit /b

:test
if exist "Main Folder" rd /s /q "Main Folder"
call :prep "Main Folder\Folder2\Folder3a" "File1.EXT"
call :prep "Main Folder\Folder2\Folder3b" "File2.EXT"
call :prep "Main Folder\Folder2\Folder3c" "File3.EXT"
call :prep "Main Folder\Folder2\Folder3d" "File1.EXT"
call :prep "Main Folder\Folder3\Folder3a" "File1.EXT"
call :prep "Main Folder\Folder3\Folder3b" "File2.EXT"
call :prep "Main Folder\Folder3\Folder3c" "File3.EXT"
call :prep "Main Folder\Folder3\Folder3d" "File1.EXT"
pushd "Main Folder" || exit /b 1
echo Prepared to test.
pause
exit /b

:prep
if /i not exist "%~1" md "%~1"
if /i not exist "%~1\%~2" type nul > "%~1\%~2"
exit /b

intregrated测试代码使测试更容易。 如果需要,删除测试代码。 使用test作为第一个参数进行测试,即main.cmd test

基于您在How to create batch file that move files from sub-folder up one level renaming duplicates?发布的循环 循环使您获得目标文件路径和目标目录路径。

在循环和第1循环的每个循环中调用标签:move 确定目标文件是否不存在。如果不存在,那样做 移动并退出标签。如果确实存在,则使用另一个循环 如果文件名以(N)结束N,则检测并修剪文件名 一个介于1和9之间的数字。然后它进入另一个循环移动 目标文件名,其中第一个可用(N)附加到名称。

D:\的根目录中测试。我得到的输出是:

D:\> main.cmd test
Prepared to test.
Press any key to continue . . .
1. move "D:\Main Folder\Folder2\Folder3a\File1.EXT" "D:\Main Folder\Folder2"
        1 file(s) moved.
1. move "D:\Main Folder\Folder2\Folder3b\File2.EXT" "D:\Main Folder\Folder2"
        1 file(s) moved.
1. move "D:\Main Folder\Folder2\Folder3c\File3.EXT" "D:\Main Folder\Folder2"
        1 file(s) moved.
2. move "D:\Main Folder\Folder2\Folder3d\File1.EXT" "D:\Main Folder\Folder2\File1 (1).EXT"
        1 file(s) moved.
1. move "D:\Main Folder\Folder3\Folder3a\File1.EXT" "D:\Main Folder\Folder3"
        1 file(s) moved.
1. move "D:\Main Folder\Folder3\Folder3b\File2.EXT" "D:\Main Folder\Folder3"
        1 file(s) moved.
1. move "D:\Main Folder\Folder3\Folder3c\File3.EXT" "D:\Main Folder\Folder3"
        1 file(s) moved.
2. move "D:\Main Folder\Folder3\Folder3d\File1.EXT" "D:\Main Folder\Folder3\File1 (1).EXT"
        1 file(s) moved.

如图所示,移动了2个文件,并在文件名后附加(1)。 这是以2.开头的行。以1.开头的行有 使用未修改的文件名移动。

答案 1 :(得分:0)

此评论批处理文件可用于此任务:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem Search for any file two directory levels below specified directory
rem and pass to subroutine MoveFile the name of the file with full path.

for /D %%A in ("C:\Main Folder\*") do (
    for /D %%B in ("%%A\*") do (
       for /F "delims=" %%I in ('dir "%%B\*" /A-D /B /S 2^>nul') do call :MoveFile "%%I"
    )
)

endlocal
goto :EOF

:MoveFile
set "FilePath=%~dp1"
set "FileNameOnly=%~n1"
set "FileNameFull=%~1"
set "FileName+Ext=%~nx1"
set "FileExtension=%~x1"

rem For files staring with a dot and not containing one more dot.
if "%FileNameOnly%" == "" set "FileNameOnly=%~x1" & set "FileExtension="

rem Get path to parent folder ending with a backslash.
for /F "delims=" %%J in ("%FilePath:~0,-1%") do set "FileParent=%%~dpJ"

rem Uncomment the line below to see the values of the six File* variables.
rem set File & echo/

rem Does a file with current file name not exist in parent folder?
if not exist "%FileParent%%FileName+Ext%" (
    rem Move the file to parent folder and if this was successful
    rem delete the folder of the moved file if being empty now.
    move "%FileNameFull%" "%FileParent%%FileName+Ext%" >nul
    if not errorlevel 1 rd "%FilePath%" 2>nul
    goto :EOF
)

set "FileNumber=1"
:NextFile
if exist "%FileParent%%FileNameOnly%_%FileNumber%%FileExtension%" set /A "FileNumber+=1" & goto NextFile

move "%FileNameFull%" "%FileParent%%FileNameOnly%_%FileNumber%%FileExtension%" >nul
if not errorlevel 1 rd "%FilePath%" 2>nul
goto :EOF

给出示例的结果是:

C:\Main Folder\Folder2\File1.EXT
C:\Main Folder\Folder2\File1_1.EXT
C:\Main Folder\Folder2\File2.EXT
C:\Main Folder\Folder2\File3.EXT
C:\Main Folder\Folder3\File1.EXT
C:\Main Folder\Folder3\File1_1.EXT
C:\Main Folder\Folder3\File2.EXT
C:\Main Folder\Folder3\File3.EXT

第二次运行批处理文件不会改变任何内容。

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • call /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • move /?
  • rd /?
  • rem /?
  • set /?
  • setlocal /?

另见: