简体   繁体   English

查找所有文件并复制到另一个保留文件夹结构的目标位置

[英]Find all files and copy to another destination keeping the folder structure

I have a folder structure with a bunch of *.jpg files scattered across the folders. 我有一个文件夹结构,其中有一堆*.jpg文件分散在文件夹中。

Now I want to find some files listed in a CSV file (one column only) or a text file line by line like 现在,我想逐行查找CSV文件(仅一列)或文本文件中列出的某些文件,例如

one.jpg  
ten.jpg  
five.jpg

and copy all those *.jpg files to another folder keeping the folder structure like: 并将所有这些*.jpg文件复制到另一个文件夹,并保持以下文件夹结构:

outputfolder\somefolder\somefolder\one.jpg

outputfolder\somefolder\ten.jpg

outputfolder\somefolder\somefolder\somefolder\five.jpg

How can I achieve this? 我该如何实现?

Here is what I've tried 这是我尝试过的

@echo off 
CLS 
REM CHECK FOR ADMIN RIGHTS 
COPY /b/y NUL %WINDIR%\06CF2EB6-94E6-4a60-91D8-AB945AE8CF38 >NUL 2>&1 
IF ERRORLEVEL 1 GOTO:NONADMIN 
DEL %WINDIR%\06CF2EB6-94E6-4a60-91D8-AB945AE8CF38 >NUL 2>&1 
:ADMIN 
REM GOT ADMIN RIGHTS 
COLOR 
1F ECHO Please wait... 
FOR /R "%~dp0" %%I IN (.) DO 
for /f "usebackq delims=" %%a in ("%~dp0list.txt") do 
echo d |xcopy "%%I\%%a" "C:\B2B_output_files" /e /i 
COLOR 2F 
PAUSE 
GOTO:EOF 
:NONADMIN 
REM NO ADMIN RIGHTS 
COLOR 4F 
pause 
GOTO:EOF 

Stack Overflow is not a free code writing service, see help topic What topics can I ask about here? Stack Overflow不是免费的代码编写服务,请参阅帮助主题。在这里,我可以问哪些主题?

However, I have nevertheless written the entire batch code for this task. 但是,我仍然为此任务编写了整个批处理代码。 Learn from this commented code and next time try to write the batch code by yourself and ask only if you stick on a problem you can't solve by yourself after several trials and not finding a solution on Stack Overflow or any other website. 从此注释代码中学习,下次尝试自己编写批处理代码,仅询问是否遇到无法在Stack Overflow或任何其他网站上找到解决方案后自行解决的问题。

The paths of source and target base folder must be defined at top of the batch script below. 必须在下面的批处理脚本的顶部定义源和目标基本文件夹的路径。

The text file containing the name of the files to copy line by line must be named FileNames.txt and must be stored in source base folder with using batch code below. 包含要逐行复制的文件名的文本文件必须命名为FileNames.txt并且必须使用下面的批处理代码存储在源基本文件夹中。

@echo off
setlocal EnableExtensions EnableDelayedExpansion

rem Define source and target base folders.

rem Note:

rem The paths should not contain an equal sign as then the
rem string substitutions below would not work as coded. The
rem target base folder can be even a subfolder of the source
rem base folder.

set "SourceBaseFolder=C:\Temp"
set "TargetBaseFolder=C:\Temp\OutputFolder"

rem Set source base folder as current directory. The previous
rem current directory is restored by command endlocal at end.

if not exist "%SourceBaseFolder%\*" (
    echo %~nx0: There is no folder %SourceBaseFolder%
    set "ErrorCount=1"
    goto HaltOnError
)

cd /D "%SourceBaseFolder%"

if not exist "FileNames.txt" (
    echo %~nx0: There is no file %SourceBaseFolder%\FileNames.txt
    set "ErrorCount=1"
    goto HaltOnError
)

rem For each file name in text file FileNames.txt in
rem source base folder the loops below do following:

rem 1. Search recursively for a file with current file name
rem    in entire directory tree of source base folder.

rem 2. If a file could be found, check its path. Skip the
rem    file if the path of found file contains the target
rem    folder path to avoid copying files to itself. This
rem    IF condition makes it possible that target base
rem    folder is a subfolder of source base folder.

rem 3. Create the folders of found file relative to source
rem    base path in target base folder. Then check if this
rem    was successful by verifying if the target folder
rem    really exists and copy the file on existing folder or
rem    output an error message on failure creating the folder.

set "ErrorCount=0"
for /F "usebackq delims=" %%N in ("FileNames.txt") do (
    for /R %%J in ("%%N*") do (
        set "FilePath=%%~dpJ"
        if "!FilePath:%TargetBaseFolder%=!" == "!FilePath!" (
            set "TargetPath=%TargetBaseFolder%\!FilePath:%SourceBaseFolder%\=!"
            md "!TargetPath!" 2>nul
            if exist "!TargetPath!\*" (
                echo Copying file %%~fJ
                copy /Y "%%~fJ" "!TargetPath!" >nul
            ) else (
                set /A ErrorCount+=1
                echo Failed to create directory !TargetPath!
            )
        )
    )
)

:HaltOnError
if %ErrorCount% NEQ 0 (
    echo.
    pause
)
endlocal

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully. 为了了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • call /? ... for an explanation of %~nx0 ...用于%~nx0的解释
  • copy /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • md /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?

And read also the Microsoft article about Using command redirection operators to understand 2>nul for suppressing error messages written to STDERR . 并阅读有关使用命令重定向运算符的Microsoft文章,以了解2>nul抑制写入STDERR的错误消息。

The following code should do what you asked for: 以下代码应按您的要求执行:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "LISTFILE=copylist.txt"
set "SOURCE=.\source"
set "DESTIN=.\destin"
for /F "usebackq eol=| delims=" %%L in ("%LISTFILE%") do (
    for /F "eol=| delims=" %%F in ('
        cd /D "%SOURCE%" ^
            ^& xcopy /L /S /I /Y ".\%%~L*" "%TEMP%" ^
            ^| findstr /I /R "^\..*\\%%~L$"
    ') do (
        2> nul md "%DESTIN%\%%F\.."
        copy /B /-Y "%SOURCE%\%%F" "%DESTIN%\%%F"
    )
)
endlocal
exit /B

It relies on the fact that xcopy outputs relative paths to the console if a relative source path is given, and that it features a switch /L that tells it not to copy anything but list what would be copied without the switch. 它依赖于以下事实:如果给出了相对源路径,则xcopy将向控制台输出相对路径,并且它具有一个开关/L ,它告诉它不复制任何内容,而是列出不使用该开关将被复制的内容。 There is also the switch /S which defines to search for the source item recursively also within subdirectories. 还有/S开关,它定义为也在子目录内递归搜索源项目。

There is a small problem though which requires to be worked around: xcopy /S only walks through subdirectories if source contains a wildcard * or ? 尽管有一个小问题需要解决: xcopy /S仅在源包含通配符*?遍历子目录? , but not if a dedicated file name is given. ,但如果指定了专用文件名,则不会。 That is why * is appended to the file name. 这就是在文件名后加上*原因。 Since this could also match some unintended items of course, findstr is used to filter them out. 由于这当然也可以匹配某些意外项目,因此使用findstr过滤掉它们。

So basically there is a for /F loop that iterates through the items listed in the text file copylist.txt . 因此,基本上有一个for /F循环可循环访问文本文件copylist.txt列出的项目。 Within this loop another for /F is nested that enumerates the output of the aforementioned findstr -filtered xcopy /L /S output, which receives the items of the outer loop one after another. 在此循环中for /F嵌套了另一个for /F ,该枚举枚举上述findstr过滤的xcopy /L /S输出的输出,该输出一个接一个地接收外循环的项。 The embedded cd command ensures to be in the source directory. Embedded cd命令确保位于源目录中。 The destination of xcopy is just an existing directory to avoid error messages (remember nothing is actually copied due to /L ). xcopy的目标只是一个现有目录,以避免出现错误消息(请记住,由于/L实际上没有任何内容被复制)。

The inner loop bopy contains an md command that creates the destination directory (tree), if not existing ( 2> nul avoids error messages if has already been created earlier), and a copy command which actually performs the copying activity; 内部循环bopy包含一个创建目标目录(树)的md命令(如果尚不存在)( 2> nul避免了先前已创建的错误消息),以及一个实际执行复制活动的copy命令。 the switch /-Y defines to prompt the user in case an item already exists at the destination location, you can change it to /Y to overwrite without asking. 开关/-Y定义了在目标位置已经存在某个项目的情况下提示用户的情况,您可以将其更改为/Y以覆盖而无需询问。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将文本文件中具有字符串结构的多个子文件夹中与字符串匹配的文件复制到另一个目标文件夹 - Copy files matching string(s) in a text file out of many subfolders with folder structure to another destination folder 如何使用Windows命令将文件夹结构和文件复制到目标位置? - How to copy the folder structure and files into the destination using a Windows command? 将通配符文件夹结构文件移动到目标文件夹 - Move Wildcard Folder structure files to a destination folder Windows批处理文件; 找到特定的文件类型并复制到保留相对文件夹结构的文件夹 - Windows Batch file; find specific file type and copy to a folder keeping the relative folder structure 递归地将一个随机文件复制到另一个文件夹,同时保持文件夹结构 - Copy one random file to another folder recursively whilst keeping folder structure 将路径以分号分隔的 source.txt 文件的文件列表复制到目标文件夹,保留其源路径 - copy list of files whose paths are in semi colon delimited source.txt file to destination folder keeping their souce paths 将文件夹中的所有文件(包括所有子文件夹递归复制)复制到另一个文件夹中 - Copy all files in a folder (including all sub-folders recursively) into another folder 如何将基于列表(txt)的文件批量复制到具有相同目录结构的另一个文件夹中? - How to batch copy files based on a list (txt) in to another folder with same directory structure? 搜索文件夹结构并复制到Windows OS中的另一个文件夹 - search for a folder structure and copy to another folder in windows OS 批量将文件复制到另一个文件夹 - Batch to copy files to another folder with breaks
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM