как я могу переместить содержимое одного дерева каталогов в другое?

<p>у меня есть каталог, который содержит файлы и несколько уровней подкаталогов:</p><pre><code>c:\source </code></pre><p>я хотел бы переместить содержимое c:\source в:</p><pre><code>c:\destination </code></pre><p>требования:</p><ul> <li>все файлы и все подкаталоги <em>в пределах</em> c:\sourcedata должны быть перемещены</li> <li>я буду выполнять команду в командном файле</li> <li>я не могу использовать powershell или любые другие языки сценариев</li> </ul><p><strong>попытка 0</strong></p><pre><code>xcopy /e "c:\source" "c:\destination" </code></pre><p>это отлично работает, но копирует вместо ходов. я не могу скопировать, а затем удалить источник, так как я перемещаю очень большой набор файлов, и на диске недостаточно места для двух копий одновременно.</p><p><strong>попытка 1</strong></p><pre><code>move "c:\source" "c:\destination" </code></pre><p>это перемещает весь каталог c:\source <em>в</em> c:\destination, поэтому я получаю:</p><pre><code>c:\destination\source </code></pre><p><strong>попытка 2</strong></p><p>с некоторой помощью <a href="https://stackoverflow.com/questions/210413">этот вопрос и принятый ответ</a> я придумал: </p><pre><code>for /r "c:\source" %%x in (*) do move "%%x" "c:\destination" </code></pre><p>это перемещает файлы в c:\source, но не подкаталоги или их содержимое. обратите внимание, что я использовал %% x вместо% x, так как использую его в командном файле.</p><p>использование for кажется многообещающим, но я не уверен, что использовал правильный синтаксис? я что-то пропустил?</p><p><strong>попытка 3</strong></p><p>как предложил ник d, я попытался переименовать:</p><p>переименовать "c:\source" пункт назначения</p><p>для примера сценария, который я дал, это прекрасно работает. к сожалению, мой настоящий каталог <em>destination</em> находится на другом уровне, чем каталог <em>source</em>, и это не поддерживается:</p><pre><code>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. </code></pre><p>я получаю «синтаксис команды неверен». ошибки, если я пытаюсь указать более сложный путь назначения, например:</p><pre><code>rename "c:\source" "c:\myotherdirectory\destination" rename "c:\source" "myotherdirectory\destination" </code></pre>

<p><strong> обновление </strong>:</p><p>приспособленный код к. проверьте, существуют ли папки в месте назначения, и в этом случае переместите файлы в этой папке (и продолжите обход структуры исходного каталога), в противном случае переместите папку оптом.</p><p>в конце сценария исходная папка полностью удаляется, чтобы исключить эти папки, файлы которых были перемещены в уже существующую папку в месте назначения (то есть эти папки были очищены, но не удалены в источнике).</p><p>кроме того, мы проверяем, является ли папка пустой и уже существует в месте назначения, и в этом случае мы ничего не делаем (и оставляем исходную папку для удаления до последней строки скрипта). невыполнение этого приводит к «неверный синтаксис имени файла, имени каталога или метки тома». ошибки.</p><p>уф! пожалуйста, дайте мне знать, как вы справляетесь с этим! я проверил это, и, кажется, работает хорошо.</p><pre><code>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 </code></pre>

<p>несомненно, используйте robocopy. это простой, но чрезвычайно полезный инструмент.</p><pre><code>robocopy /move /e sourcedir destdir </code></pre><p>это приведет к перемещению всех файлов и папок, включая пустые, при удалении каждого исходного файла после его перемещения.</p><p>если у вас не установлена robocopy, вы можете загрузить ее самостоятельно или в составе набора ресурсов microsoft.</p>

<p>как отправлено в twitter: попробуйте объединить попытку 3 с попыткой 1. переименуйте, чтобы получить правильную папку назначения, затем переместите «место назначения» в правильное место.</p>

<p>поскольку xcopy работает, вы можете использовать xcopy и delete, это обходной путь, но должен ли он работать?</p>

<p>на vista использовать</p><pre> robocopy исходный пункт назначения /mir /mir .. отражает полное дерево каталогов (также удаляет файлы в месте назначения) </pre><p>else</p><pre> хсор </pre><p>конечно, вы должны удалить источник впоследствии :)</p>

<pre><code>@echo on set source=c:\source set destination=c:\destination xcopy %source%\* %destination%\* /s /e /i /y pause </code></pre><p>я использую пакетный файл, как это ...</p><p>или просто позвоните:</p><pre><code>xcopy c:\source\* c:\destination\* /s /e /i /y </code></pre>

<blockquote> <p>у меня есть каталог, который содержит файлы и ряд уровней подкаталоги:</p> <p>c:\source</p> <p>я хотел бы переместить содержимое c:\источник в:</p> <p>c:\destination</p> </blockquote><p>может быть, я что-то упустил, но вы не можете просто переименовать папку?</p>

<p>может быть, немного не по теме, но все же полезно:</p><p>некоторые люди предлагают просто скопировать + удалить исходные файлы, но перемещение файлов - это не то же самое, что копирование + удаление!</p><p>при использовании функции <strong>(x) copy</strong> вы <strong>выделяете новое пространство</strong> на <strong>том же томе</strong> на жестком диске. после копирования файлов файлы <strong>old</strong> (старое выделенное пространство, которое требовалось для файлов) помечаются как <strong>удаленный</strong>. в то время как вы достигнете того же результата, что и конечный пользователь, перемещение делает что-то другое и более эффективное.</p><p><strong>перемещение</strong> файлов фактически изменяет только некоторые записи в <strong>mft</strong> (таблица основных файлов). эти изменения состоят только из другого пути, по которому пользователь может найти свои файлы. физически файлы по-прежнему остаются в тех же секторах на жестком диске.</p>

<p>в ответ на ответ уфукгуна:</p><pre><code>xcopy c:\source\* c:\destination\* /s /e /i /y </code></pre><p>/ s - копирует каталоги и подкаталоги, кроме пустых.<br> /e - копирует каталоги и подкаталоги, в том числе пустые. то же, что/s/e. может использоваться для изменения/t.<br> /i - если место назначения не существует и копируется более одного файла, предполагается, что место назначения должно быть каталогом.<br> /y - подавляет запрос на подтверждение того, что вы хотите перезаписать существующий файл назначения.</p><p>как указано в другом ответе, использование xcopy может быть не столь эффективным, как если бы это была собственная команда перемещения, которая изменяет только указатели в файловой системе.</p>

<p>если все, что вы пытаетесь сделать, это переместить каталог и содержимое на один уровень выше:</p><pre><code>move folder\_you\_wan\_to\_move .. </code></pre><p>обратите внимание, что .. относится к следующему каталогу вверх.</p>

<p>я оставляю этот код, написанный мною на основе попытки ljs, он перемещает деревья каталогов, как это делает windows, перезаписывая файлы, уже существующие в месте назначения, теми, которые находятся в источнике, и избегая медленного метода копирования и стирания, за исключением случаев, когда место назначения находится в другой диск.</p><p>если ваш s.o не на английском языке, необходимо заменить строку 6 текстом, используемым командой dir, когда он находит 0 файлов.</p><p><strong> moveir.bat <em>source\_dir destination\_dir</em> </strong></p><pre><code>@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 </code></pre>

<p>я думаю, что самое простое, что вы можете сделать, это изменить вашу попытку 2</p><p>от</p><pre><code>move "c:\source" "c:\destination" </code></pre><p>в</p><pre><code>move "c:\source\*" "c:\destination" </code></pre><p>поцелуй ;-)</p><p><strong> правка </strong>: похоже, это не работает, поэтому мой совет - убрать дрянную командную строку dos и использовать cygwin с bash в качестве оболочки! (или просто добавьте к пути двоичные файлы cygwin, чтобы вы могли использовать <code>mv</code> в dos, таким образом, не изменяя shell в соответствии с вашими требованиями).</p>

<p>я использую утилиту под названием xxcopy. он может перемещать файлы и иметь много полезных опций, вы можете использовать его так:</p><pre><code>xxcopy c:\source c:\destination /e /rc </code></pre><p>варианты:</p><ul> <li><p>/ e копировать все, даже пустые папки</p></li> <li><p>/ rc для удаления каждого исходного файла после каждой успешной копии</p></li> </ul><p>вы можете скачать бесплатную копию xxcopy для личного пользования по адресу: <a href="http://www.xxcopy.com/xcpydnld.htm">http://www.xxcopy.com/xcpydnld.htm</a> </p>