批处理文件,使用计数器将树中的所有.sql文件复制到单个文件夹,用于同名文件

时间:2016-10-04 17:24:25

标签: batch-file

我正在寻找一些帮助来设置一个批处理脚本来遍历整个目录并将所有.sql文件复制到一个文件夹中。我可以使用FOR循环轻松完成此操作,但如果不同目录中的两个或多个文件具有相同的名称,我就会遇到麻烦。我试图使用计数器解决这个问题,但我无法让它专门针对单个文件名。

到目前为止我的代码:

set /A n=0

for /R %source% %%G in (*.sql) do (
    if exist %destination%\sql_files\%%~nxG (
        set /A n+=1
        set "full=%%G"
        set "name=%%~nG"
        set "ext=%%~xG"
        setlocal enabledelayedexpansion
        copy "!full!" "!destination!\sql_files\!name!(!n!)!ext!" >nul
        endlocal
    ) else (
        copy "%%G" "%destination%\sql_files\" >nul
    )
)

例如,如果我有:

%source%\dir1\file1.sql
%source%\dir1\file2.sql
%source%\dir2\file1.sql
%source%\dir2\file2.sql
%source%\dir3\file1.sql

我最终得到了:

file1.sql
file1(1).sql
file1(3).sql
file2.sql
file2(2).sql

我希望看到的是:

file1.sql
file1(1).sql
file1(2).sql
file2.sql
file2(1).sql

我认为我的答案可能在于子程序,但我无法弄清楚这项工作的逻辑。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

这是一个可以满足您需求的脚本。它依赖于目标目录最初为空的事实:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "SOURCE=."
set "DESTINATION=..\sql_files"
set "PATTERN=*.sql"
set "TMPFILE=%TEMP%\%~n0_%RANDOM%.tmp"

rem // Create target directory, check whether it is empty:
2> nul md "%DESTINATION%"
(2> nul dir /B /A "%DESTINATION%\*.*" | > nul find /V "") && (
    >&2 echo Target directory "%DESTINATION%" is not empty!
    exit /B 1
)

rem /* Write list of files to temporary file; each line holds
rem    the pure file name and the full path, separated by `:`: */
if not defined SOURCE set "SOURCE=."
> "%TMPFILE%" (
    for /R "%SOURCE%" %%F in ("%PATTERN%") do (
        echo :%%~nxF:%%~fF
    )
)

rem // Read temporary file with lines sorted by file names:
set "PREV=:" & set /A "INDEX=0"
for /F "tokens=1,* delims=:" %%E in ('sort "%TMPFILE%"') do (
    rem // Cache file name parts and full path:
    set "FILE=%%E"
    set "NAME=%%~nE"
    set "EXT=%%~xE"
    set "FULL=%%F"
    rem // Compare current with previous file name:
    setlocal EnableDelayedExpansion
    if /I not "!FILE!"=="!PREV!" (
        endlocal
        rem // Reset index if names do not match:
        set /A "INDEX=0"
    ) else (
        endlocal
        rem // Increment index if names do match:
        set /A "INDEX+=1"
    )
    rem // Build new file nase name:
    setlocal EnableDelayedExpansion
    if !INDEX! GTR 0 (
        set "NAME=!NAME!(!INDEX!)"
    )
    rem // Copy file and rename accordingly:
    > nul copy "!FULL!" "!DESTINATION!\!NAME!!EXT!"
    endlocal
    rem // Cache processed file name:
    set "PREV=%%E"
)

rem // Delete temporary file:
del "%TMPFILE%"

endlocal
exit /B