Batch script to copy files listed in text file from a folder and its subfolders to a new location

后端 未结 1 338
忘掉有多难
忘掉有多难 2021-01-16 13:58

I would like a batch file to copy all of the files listed in a text file from one destination to another. The source destination may have multiple subfolders and I would lik

1条回答
  •  被撕碎了的回忆
    2021-01-16 14:37

    First, you need to enable extended command line

    SETLOCAL ENABLEEXTENSIONS
    

    so you can use the extended FOR loop. Second, you need to enable delayed expansion of environment variables

    SETLOCAL ENABLEDELAYEDEXPANSION
    

    so you can check if searched file was found later.

    Here is the result:

    @echo off
    SETLOCAL ENABLEEXTENSIONS
    SETLOCAL ENABLEDELAYEDEXPANSION
    
    SET src=.\sourcefolder\
    SET dst=.\destinationfolder\
    SET file_list=.\files.txt
    
    FOR /F %%f IN (%file_list%) DO (
        SET found=false
        FOR /F "usebackq" %%s IN (`where /R %src% %%f`) DO (
            SET found=true
            echo "%%s => %dst%\%%f"
            @copy /y "%%s" "%dst%\%%f" 
        )
        IF "!found!" == "false" (
            echo %%f is not found!
        )
    )
    

    ENABLEDELAYEDEXPANSION is needed here for variable %found%, without it %found% will always be false. Furthermore, to expand environment at runtime you must use !found! syntax.

    You can call it like

    batch.bat > result.log
    

    and the results will be writen to file result.log


    UPDATE: here is a version of bacth without variable found and with suggestions from @aschipfl:

    @echo off
    SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
    
    SET "src=.\sourcefolder\"
    SET "dst=.\destinationfolder\"
    SET "file_list=.\files.txt"
    
    FOR /F "usebackq eol=| delims=" %%f IN ("%file_list%") DO (
        rem just searching to find out existense of file
        WHERE /Q /R "%src%" "%%f"
        IF "!ERRORLEVEL!" == "0" (
            FOR /F "usebackq eol=| delims=" %%s IN (`WHERE /R "%src%" "%%f" 2^> nul`) DO (
                echo "%%s => %dst%\%%f"
                @copy /y "%%s" "%dst%\%%f" 
            )
        ) ELSE (
            echo %%f is not found!
        )
    )
    

    This version can handle files with a space symbol in the filename.
    But both of the solutions have same restriction: sourcefolder can't contain any spaces in the name. For some reason command WHERE /R "%src%" "%%f" doesn't working, while WHERE /R %src% "%%f" working just as expected.


    UPDATE2: here is the version, that produces result.log:

    @echo off
    SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
    
    SET "src=.\sourcefolder\"
    SET "dst=.\destinationfolder\"
    SET "file_list=.\files.txt"
    SET "out=.\result.log"
    echo > %out%
    
    FOR /F "usebackq eol=| delims=" %%f IN ("%file_list%") DO (
        rem just searching to find out existense of file
        WHERE /Q /R %src% "%%f"
        IF "!ERRORLEVEL!" == "0" (
            FOR /F "usebackq eol=| delims=" %%s IN (`WHERE /R %src% "%%f"`) DO (
                echo "%%s => %dst%\%%f" >> %out%
                @copy /y "%%s" "%dst%\%%f" 
            )
        ) ELSE (
            echo %%f is not found! >> %out%
        )
    )
    

    0 讨论(0)
提交回复
热议问题