如果名称匹配,请使用更长名称的文件

时间:2015-02-02 13:20:00

标签: windows batch-file

我有一些批处理脚本代码,可以递归地将文件夹及其子文件夹的内容复制到单个文件夹中:

for /r %f in (*) do @copy "%f" .

我想稍微改变一下这个行为,所以如果两个或多个文件具有相同的名称,我想只复制一个文件路径最长的文件路径(根据深度是多少,不是字符长度。)

例如,如果我们有:

C:/Desktop/Folder/File1

C:/Desktop/Folder/NewFolder/File1

在这种情况下,我们将获取第二个文件并将其复制到新文件夹中。

我不会相信这可以通过批处理脚本实现,但我可能不正确。

感谢。

2 个答案:

答案 0 :(得分:2)

你可能已经在那里了,因为FOR /R将从上到下在同一个分支中递归,你将以强制覆盖以前复制的文件结束最深的文件

for /r %f in (*) do @copy /Y "%f" \destination

答案 1 :(得分:0)

此代码中的复制操作仅回显给控制台。如果输出正确,请在echo

之前删除copy命令
@echo off
    setlocal enableextensions disabledelayedexpansion

:: CONFIGURATION

    rem Source and target folders for copy operation
    set "sourceFolder=%cd%"
    set "targetFolder=x:\somewhere"

    rem Temporary files needed 
    set "tempList=%temp%\%~nx0.%random%%random%.tmp"
    set "endList=%tempList%.end"

    rem Variable used for level padding
    set "level=10000"


:: SEARCH FILES

    rem For each folder under the indicated source 
    (for /r "%sourceFolder%" /d %%a in (.) do (

        rem Retrieve the deep level splitting the folder name
        rem and counting the segments
        set "folder=%%a"
        setlocal enabledelayedexpansion & for %%b in ("!folder:\=" "!") do set /a "level+=1"

        rem For each file in the folder output filename, level and full file path
        rem A pipe character is used as delimiter between the tokens
        for %%b in (!level!) do (
            endlocal 
            for %%c in ("%%~fa\*") do (echo(^|%%~nxc^|%%b^|%%~fc)
        )

        rem And send everything to a temporary file
    )) > "%tempList%"

    rem Sort the temporary file on filename and level in descending order. 
    sort /r "%tempList%" /o "%endList%"

    rem Now for each group of files with same name, the first one is the 
    rem file located in the deepest folder


:: COPY FILES    

    rem No file has been copied 
    set "lastFile=|"

    rem For each record in the sorted file list, split it in three tokens
    rem using the included pipe charactes as delimiters
    for /f "usebackq tokens=1-3 delims=|" %%a in ("%endList%") do (
        setlocal enabledelayedexpansion
        for %%d in ("!lastFile!") do (
            endlocal

            rem If the name of the file is different to 
            rem the previous one, we have started a new group and as the first file
            rem is the deepest one, copy it and store the new file name 
            if not "%%a"=="%%~d" (
                echo copy /y "%%c" "%targetFolder%"
                set "lastFile=%%a"
            )
        )
    )

:: CLEANUP

    rem Remove the temporary files 
    del /q "%tempList%"
    del /q "%endList%"