I have a script that extracts all files from all sub-directories and deletes the empty sub-directories afterwards, the part that extracts reads:

for /r %%a in (*.*) do move "%%a" "%~dp0"

Is there a way to do this with the exception of sub-directories named "_Unsorted"? I know xcopy has an /exclude option, so something like

for /r %%a in (*.*) do xcopy "%%a" "%~dp0" /exclude "\_Unsorted\"

would almost work, but I'm not sure how to delete the original after it's copied to essentially have the same result as move

有帮助吗?

解决方案 2

Some batch-only options:

  1. Add a filter into the loop body:

    for /r %%a in (*.*) do (
      (echo %%~dpa | find /i "\_Unsorted\" 1>nul) || move "%%a" "%~dp0"
    )
    

    Alternatively:

    for /r %%a in (*.*) do (
      (echo %%~dpa | find /i /v "\_Unsorted\" 1>nul) && move "%%a" "%~dp0"
    )
    

    In both versions, the find command is used to match the file's path against the substring \_Unsorted\. In the first version, find returns success if there is a match and fail otherwise. The move command is called only in case of fail, which is the effect of the || operator`.

    In the second version, the /v switch reverses the result of find and success now means no match. Accordingly, the && operator is used to call move in case of success.

  2. Apply the filter to the file list, so that the loop never iterates over _Unsorted entries.

    for /f "delims=" %%a in (
      'dir /s /b ^| find /i /v "\_Unsorted\"'
    ) do move "%%a" "%~dp0"
    

    This is a more essential change to the original script than the previous option, as this replaces the for /r loop with a for /f one.

    Basically, a for /f loop is used to read/parse a piece of text, a text file or a command's output. In this case, the dir command provides a complete list of files in the current directory's tree and the find command filters out those containing \_Unsorted\ in their paths. The for /f loop reads the list after it's been filtered down by find, which means it never hits files stored in _Unsorted (sub)folders.

其他提示

Can you use robocopy?

robocopy from\path to\path *.* /mov /e /xd _Unsorted

/mov: move rather than copy (delete the source after copying)

/e: recursive (including empty subdirectories)

/xd _Unsorted: exclude directories named _Unsorted

Answer 3 above, using ROBOCOPY, creates a tree of (possibly empty) subdirectories.

The following requires the obtaining of xxcopy

xxcopy c:\filematch d:\dest\ /SGF /RC

copies from c: to folder d:\dest

/SGF recurses subdirectories but flattens the result at the destination. In the event of filename collision, it appends .0001 to the first duplicate filename. So /SGF copies every matching file from the source drive, no matter what subdirectory it occupies, into a specified destination folder.

/RC removes the files from the source following a successful copy, AKA it moves them.

Not sure if it is what the OP wanted, but this discussion helped me!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top