windows 如何将一个目录树的内容移动到另一个目录树中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1118540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 06:34:37  来源:igfitidea点击:

How can I move the contents of one directory tree into another?

windowsbatch-filecmd

提问by Tom Robinson

I have a directory which contains files and a number of levels of subdirectories:

我有一个目录,其中包含文件和多个级别的子目录:

C:\Source

I would like to move the contents of C:\Source into:

我想将 C:\Source 的内容移动到:

C:\Destination

Requirements:

要求:

  • All files and all subdirectories withinC:\SourceData must be moved
  • I will be running the command in a batch file
  • I can't use Powershell or any other scripting languages
  • 所有文件和所有子目录 中的C:\ SourceData必须移动
  • 我将在批处理文件中运行命令
  • 我不能使用 Powershell 或任何其他脚本语言

Attempt 0

尝试 0

XCOPY /E "C:\Source" "C:\Destination"

This works perfectly, but it copies instead of moves. I can't copy then delete the source as I'm moving a very large set of files and there isn't enough disk space to have two copies of them at a time.

这工作得很好,但它复制而不是移动。我无法复制然后删除源文件,因为我正在移动非常大的文件集,并且没有足够的磁盘空间来一次拥有两个副本。

Attempt 1

尝试 1

MOVE "C:\Source" "C:\Destination"

This moves the entire C:\Source directory intoC:\Destination so I end up with:

这将整个 C:\Source 目录移动C:\Destination 所以我最终得到:

C:\Destination\Source

Attempt 2

尝试 2

With some help from this question and accepted answerI came up with:

这个问题的一些帮助和接受的答案下,我想出了:

for /r "C:\Source" %%x in (*) do move "%%x" "C:\Destination"

This moves the files within C:\Source but not the subdirectories or their contents. Note that I used %%x instead of %x as I'm using it in a batch file.

这会移动 C:\Source 中的文件,但不会移动子目录或其内容。请注意,我使用 %%x 而不是 %x ,因为我在批处理文件中使用它。

Using FOR seems promising but I'm not sure I've used the right syntax? Have I missed something?

使用 FOR 似乎很有前途,但我不确定我是否使用了正确的语法?我错过了什么吗?

Attempt 3

尝试 3

As suggested by Nick D, I tried rename:

正如 Nick D 所建议的,我尝试重命名:

RENAME "C:\Source" Destination

重命名 "C:\Source" 目标

For the example scenario I gave this works fine. Unfortunately my real Destinationdirectory is at a different level to the Sourcedirectory and this doesn't seem to be supported:

对于我给出的示例场景,这个工作正常。不幸的是,我真正的Destination目录与Source目录处于不同的级别,这似乎不受支持:

C:\>REN /?
Renames a file or files.

RENAME [drive:][path]filename1 filename2.
REN [drive:][path]filename1 filename2.

Note that you cannot specify a new drive or path for your destination file.

I get "The syntax of the command is incorrect." errors if I try to specify a more complex destination path, for example:

我收到“命令的语法不正确”。如果我尝试指定更复杂的目标路径,则会出现错误,例如:

RENAME "C:\Source" "C:\MyOtherDirectory\Destination"
RENAME "C:\Source" "MyOtherDirectory\Destination"

采纳答案by ljs

Update:

更新

Adjusted code to a. check whether folders already exist at the destination, in which case move files in that folder over (and continue traversing the source directory structure), otherwise move the folder wholesale.

将代码调整为 a。检查目标是否已存在文件夹,在这种情况下,将文件夹中的文件移过(并继续遍历源目录结构),否则批发移动文件夹。

At the end of the script the source folder is removed altogether to eliminate these folders which have had their files moved over to an already existent folder at the destination (meaning these folders have been emptied but not deleted at the source).

在脚本结束时,源文件夹将被完全删除,以消除这些文件夹,这些文件夹的文件已移至目的地的现有文件夹(这意味着这些文件夹已被清空但未在源处删除)。

Additionally we check whether a folder is both empty and already exists at the destination in which case we do nothing (and leave the source folder to be deleted to the last line of the script). Not doing this results in "The filename, directory name, or volume label syntax is incorrect." errors.

此外,我们检查文件夹是否既为空又在目的地已经存在,在这种情况下我们什么都不做(并将要删除的源文件夹保留到脚本的最后一行)。不这样做会导致“文件名、目录名或卷标语法不正确”。错误。

Phew! Please let me know how you get on with this! I have tested this and it seems to be working well.

呼!请让我知道你是如何处理这件事的!我已经对此进行了测试,它似乎运行良好。

for /d /r "c:\source" %%i in (*) do if exist "c:\destination\%%~ni" (dir "%%i" | find "0 File(s)" > NUL & if errorlevel 1 move /y "%%i\*.*" "c:\destination\%%~ni") else (move /y "%%i" "c:\destination")
move /y c:\source\*.* c:\destination
rd /s /q c:\source  

回答by DavidMWilliams

Undoubtedly use robocopy. It is a simple but brilliantly useful tool.

毫无疑问,使用robocopy。这是一个简单但非常有用的工具。

robocopy /move /e sourcedir destdir

This will move all the files and folders, including empty ones, deleting each original file after it has moved it.

这将移动所有文件和文件夹,包括空文件和文件夹,并在移动后删除每个原始文件。

If you don't have robocopy installed you can download it by itself or as part of a Microsoft resource kit.

如果您没有安装 robocopy,您可以自行下载或作为 Microsoft 资源工具包的一部分下载。

回答by Fluxzoal

Maybe a little off-topic, but still usefull:

也许有点题外话,但仍然有用:

Some people suggest to just copy + delete the source files, but moving files is not the same as copying + deleting!

有人建议只复制+删除源文件,但移动文件与复制+删除不一样!

When using the (x)copyfunction, you allocate new spaceon the same volumeon a harddisk. After the copying the files, the oldfiles (the old allocated space which was required for the files) are beign marked as deleted. While you will achieve the same result as an end-user, moving does something diffrent and more efficient.

使用(x)copy函数时,您在硬盘上的同一卷分配新空间。复制文件后,文件(文件所需的旧分配空间)被标记为已删除。虽然您将获得与最终用户相同的结果,但移动会做一些不同且更高效的事情。

Movingfiles actually only changes some records in the MFT(master file table). These changes only consist of a different path for the user to locate its files. Physically the files still remain in the same sectors on the harddisk.

移动文件实际上只改变了MFT(主文件表)中的一些记录。这些更改仅包含供用户定位其文件的不同路径。从物理上讲,文件仍然保留在硬盘上的相同扇区中。

回答by axelitus

In response to ufukgun's answer:

回应 ufukgun 的回答:

xcopy C:\Source\* C:\Destination\* /s /e /i /Y

/s - Copies directories and subdirectories except empty ones.
/e - Copies directories and subdirectories, including empty ones. Same as /S /E. May be used to modify /T.
/i - If destination does not exist and copying more than one file, assumes that destination must be a directory.
/y - Suppresses prompting to confirm you want to overwrite an existing destination file.

/s - 复制目录和子目录,除了空目录。
/e - 复制目录和子目录,包括空目录。与 /S /E 相同。可用于修改/T。
/i - 如果目标不存在并且复制多个文件,则假定目标必须是一个目录。
/y - 禁止确认您要覆盖现有目标文件的提示。

As stated in another answer, using xcopy may be not as efficient as it would be a native move command that only changes pointers in the filesystem.

正如另一个答案中所述,使用 xcopy 可能不如只更改文件系统中的指针的本机移动命令那样有效。

回答by StuperUser

Since XCOPY works, you could use XCOPY and DELETE, it's a workaround, but should work?

由于 XCOPY 有效,您可以使用 XCOPY 和 DELETE,这是一种解决方法,但应该有效吗?

回答by Dynamicbyte

on Vista use

在 Vista 上使用

robocopy source destination /MIR

/MIR .. mirror a complete directory tree (also deletes files in the destination)

else

别的

xcopy

Of course you have to delete the source afterwards :)

当然你之后必须删除源:)

回答by Nick Dandoulakis

I have a directory which contains files and a number of levels of subdirectories:

C:\Source

I would like to move the contents of C:\Source into:

C:\Destination

我有一个目录,其中包含文件和多个级别的子目录:

C:\源

我想将 C:\Source 的内容移动到:

C:\目的地

Maybe I'm missing something, but can't you just rename the folder?

也许我遗漏了什么,但你不能重命名文件夹吗?

回答by David Webster

As sent on twitter: Try combining attempt 3 with attempt 1. Rename to get the destination folder correct, then move "Destination" to the correct place.

正如在 twitter 上发送的:尝试将尝试 3 与尝试 1 相结合。重命名以使目标文件夹正确,然后将“目标”移动到正确的位置。

回答by ufukgun

@echo on
set SOURCE=C:\Source
set DESTINATION=C:\Destination

xcopy %SOURCE%\* %DESTINATION%\* /s /e /i /Y

PAUSE

i use batch file like this...

我使用这样的批处理文件...

or simply call:

或者干脆打电话:

xcopy C:\Source\* C:\Destination\* /s /e /i /Y

回答by marc r p

I leave this code I have written based on ljs's attempt, It moves directory trees as Windows does, overwriting the files that already exists in destination with those in source, and avoiding the slow copy and erase method except if the destination is in a different drive.

我留下了我根据 ljs 的尝试编写的这段代码,它像 Windows 一样移动目录树,用源中的文件覆盖目标中已经存在的文件,并避免慢速复制和擦除方法,除非目标位于不同的驱动器中.

If your S.O is not in english must change line 6 with the text used by the Dir command when it finds 0 files.

如果您的 SO 不是英文,则必须使用 Dir 命令在找到 0 个文件时使用的文本更改第 6 行。

movedir.bat source_dir destination_dir

moveir.bat source_dir destination_dir

@echo off
SETLOCAL  ENABLEDELAYEDEXPANSION

if %1.==. echo movedir dir1[\*] dir2 & echo move dir1 inside dir2 overwriting coincident files & echo option \* moves only dir1 content & goto end

set S=%~f1
set D=%~f2
set "noFiles= 0 File"
set "R=0"         rem R is option [\*] flag

if %S:~-2%.==\.. set "S=%S:~,-2%" & set "R=1"

if not exist "%S%" goto paramERR
if not exist "%D%" goto paramERR

set "Trim=0" & set "Sc=%S%"
:LP
set /A Trim+=1 & (set "Sc=!Sc:~1!") & if NOT !Sc!.==. goto LP

if %R%==0 (if exist "%D%\%~n1%~x1" (set "D=%D%\%~n1%~x1")) else move /y "%S%" "%D%" & goto end

CALL:movefiles "%S%" "%D%"
for /D /R "%S%" %%I in (*) do (set "Way=%%~fI") & (set "Way=!Way:~%Trim%!") & if exist "%D%!Way!" (CALL:movefiles "%%I" "%D%!Way!") else (move /y "%%I" "%D%!Way!\.." > NUL)
rd /s/q "%S%" & if %R%==1 md "%S%"
goto end

:movefiles 
dir %1 | find "%noFiles%" > NUL & if ERRORLEVEL 1 move /y "%~1\*.*" %2 > NUL 
goto :eof

:paramERR
echo Source or Destination does not exist
:end