Pytanie w sprawie windows, cmd, batch-file – Jak mogę przenieść zawartość jednego drzewa katalogów do innego?

18

Mam katalog, który zawiera pliki i wiele poziomów podkatalogów:

C:\Source

Chciałbym przenieść zawartość C: na:

C:\Destination

Wymagania:

Wszystkie pliki i wszystkie podkatalogiw ciągu C: Dane źródłowe muszą zostać przeniesioneBędę uruchamiał polecenie w pliku wsadowymNie mogę używać Powershell ani żadnych innych języków skryptowych

Próba 0

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

To działa doskonale, ale kopiuje zamiast ruchów. Nie mogę skopiować, a następnie usunąć źródła, ponieważ przenoszę bardzo duży zestaw plików i nie ma wystarczającej ilości miejsca na dysku, aby mieć dwie kopie naraz.

Próba 1

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

Przenosi to cały katalog C:w C: Miejsce docelowe, więc kończę na:

C:\Destination\Source

Próba 2

Z pewną pomocąto pytanie i zaakceptowana odpowiedź Wymyśliłem:

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

Powoduje to przeniesienie plików w C: Źródło, ale nie podkatalogi lub ich zawartość. Zauważ, że użyłem %% x zamiast% x, ponieważ używam go w pliku wsadowym.

Korzystanie z FOR wydaje się obiecujące, ale nie jestem pewien, czy użyłem właściwej składni? Czy coś przegapiłem?

Próba 3

Jak sugerował Nick D, próbowałem zmienić nazwę:

RENAME Miejsce docelowe „C: Source”

W przykładowym scenariuszu dałem to dobrze. Niestety mój prawdziwyprzeznaczenie katalog jest na innym poziomie niżŹródło katalog i to nie wydaje się być obsługiwane:

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.

Otrzymuję „Składnia polecenia jest niepoprawna”. błędy, jeśli spróbuję określić bardziej złożoną ścieżkę docelową, na przykład:

RENAME "C:\Source" "C:\MyOtherDirectory\Destination"
RENAME "C:\Source" "MyOtherDirectory\Destination"
Jeśli RENAME działało tak, jak chciałeś, możesz przenieść się do właściwego folderu o tymczasowej nazwie, a następnie zmienić jego nazwę :) eglasius
Podczas gdy MOVE przeniesie „źródło”w „miejsce docelowe”, jeśli „miejsce docelowe” już istnieje, przeniesie „źródło”do „miejsce docelowe”, jeśli jeszcze nie istnieje. Jason Musgrove

Twoja odpowiedź

13   odpowiedzi
1

Spróbuj połączyć próbę 3 z próbą 1. Zmień nazwę, aby uzyskać poprawny folder docelowy, a następnie przenieś „Miejsce docelowe” na właściwe miejsce.

0

zydatnych opcji, możesz ich używać w ten sposób:

xxcopy C:\Source C:\Destination /E /RC

opcje :

/ E, aby skopiować wszystko, nawet puste foldery

/ RC, aby usunąć każdy plik źródłowy po każdej udanej kopii

możesz pobrać bezpłatną kopię xxcopy na własny użytek z:http://www.xxcopy.com/xcpydnld.htm

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

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

PAUSE

lub po prostu zadzwoń:

xcopy C:\Source\* C:\Destination\* /s /e /i /Y
Co robią przełączniki / s / e / i / Y? Czy powodują, że przenoszą pliki zamiast je kopiować? Tom Robinson
1

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

/ s - Kopiuje katalogi i podkatalogi oprócz pustych.
/ e - Kopiuje katalogi i podkatalogi, w tym katalogi puste. Tak samo jak / S / E. Może być użyty do modyfikacji / T.
/ i - Jeśli miejsce docelowe nie istnieje i kopiuje więcej niż jeden plik, zakłada się, że miejscem docelowym musi być katalog.
/ y - pomija monitowanie o potwierdzenie zamiaru zastąpienia istniejącego pliku docelowego.

Jak stwierdzono w innej odpowiedzi, użycie xcopy może nie być tak wydajne, jak byłoby rodzimym poleceniem przenoszenia, które zmienia jedynie wskaźniki w systemie plików.

0

z

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

do

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

POCAŁUNEK ;-)

Edytować: Wydaje się, że to nie działa, więc moja rada polega na usunięciu kiepskiej linii poleceń DOS i użyciu Cygwina z BASH jako powłoki! (lub po prostu dodaj binaria cygwin do ścieżki, aby można było użyćmv w systemie DOS, dzięki czemu nie trzeba zmieniać powłoki jako stanu wymagań).

czyż nie? :-co za gówno ... fortran
To bardzo proste, ale nie działa. Podkatalogi w C: Źródło nie jest kopiowane Tom Robinson
1

w systemie Vista

robocopy source destination /MIR

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

jeszcze

xcopy

Oczywiście musisz później usunąć źródło :)

To działałoby w wielu przypadkach, ale niestety nie mogę skopiować, a następnie usunąć źródła, ponieważ przenoszę bardzo duży zestaw plików i nie ma wystarczającej ilości miejsca na dysku, aby mieć dwie kopie na raz. Zaktualizowałem pytanie, aby to wyjaśnić. Powinienem był o tym wspomnieć wcześniej. Tom Robinson
tak, tak. Potrzebowałbyś robocopy / MOVE nie / MIR Joey
11

Aktualizacja:

Dostosowany kod do a. sprawdź, czy foldery już istnieją w miejscu docelowym, w którym to przypadku przenieś pliki w tym folderze (i kontynuuj przechodzenie przez strukturę katalogu źródłowego), w przeciwnym razie przenieś folder hurtowo.

Na końcu skryptu folder źródłowy jest całkowicie usuwany, aby wyeliminować te foldery, które miały przeniesione pliki do już istniejącego folderu w miejscu docelowym (co oznacza, że ​​te foldery zostały opróżnione, ale nie zostały usunięte u źródła).

Dodatkowo sprawdzamy, czy folder jest zarówno pusty, jak i już istnieje w miejscu docelowym, w którym to przypadku nic nie robimy (i zostawiamy folder źródłowy do usunięcia w ostatniej linii skryptu). Nie wykonanie tego spowoduje, że „Nazwa pliku, nazwa katalogu lub składnia etykiety woluminu jest niepoprawna”. błędy.

Uff! Daj mi znać, jak sobie z tym poradzisz! Przetestowałem to i wydaje się, że działa dobrze.

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  
Dzięki, spróbuję, ale na razie zabrakło mi czasu. Ostatecznie korzystałem z opcji robocopy, ponieważ łatwiej jest ją przeczytać i zrozumieć, kto odziedziczy mój kod w późniejszym terminie. Tom Robinson
Musiałem zmienić polecenie FOR, aby użyć %% i zamiast% i (ponieważ jest w pliku wsadowym), ale poza tym działa świetnie. Dziękuję Ci! Tom Robinson
Hmm, może to nie działa. Dostaję „Nazwa pliku, nazwa katalogu lub składnia etykiety woluminu jest niepoprawna”. podczas uruchamiania polecenia przenoszenia. Tom Robinson
%%~ni usuwa rozszerzenie, więc nazwa folderu z kropką zostanie przerwana - zmień na%%~nxi. Paul
24

ale doskonale przydatne narzędzie.

robocopy /move /e sourcedir destdir

Spowoduje to przeniesienie wszystkich plików i folderów, w tym pustych, usuwając każdy oryginalny plik po jego przeniesieniu.

Jeśli nie masz zainstalowanego robocopy, możesz pobrać go samodzielnie lub jako część zestawu zasobów Microsoft.

Jest to dobra odpowiedź, ale w rzeczywistości najpierw się kopiuje, a następnie usuwa. Jeśli przenosisz dużą strukturę katalogów, zajmie to trochę czasu. Podczas gdy ręczne przenoszenie go w eksploratorze byłoby prawie natychmiastowe, ponieważ wszystko, co by robił, to aktualizacja MFT. Squashman
Tak - a to co miłe to to, że nie ma żadnych zależności; jest to tylko jeden plik .exe i działa dobrze w systemach Vista, Server 2003, 2008 itd. Dopóki można go przechowywać za pomocą skryptu, będzie on miał solidny i niezawodny proces. DavidMWilliams
+1: Zapomniałem o tym, że robocopy mogą się poruszać (to musi być nazwa!). W moim przypadku nie mogę polegać na tym, że robocopy są instalowane, ale mogę łatwo dołączyć binarnie obok skryptu. Tom Robinson
1

C: Źródło

Chciałbym przenieść zawartość C: na:

C: Miejsce docelowe

Może czegoś mi brakuje, ale czy nie możesz po prostu zmienić nazwy folderu?

Niestety nie działa to, jeśli katalog docelowy nie jest na tym samym poziomie, co katalog źródłowy. Dodam więcej szczegółów do pytania niż do tego pola komentarzy. Tom Robinson
0

co próbujesz zrobić, to przenieść katalog i zawartość o jeden poziom:

MOVE folder_you_wan_to_move ..

Zauważ, że .. odnosi się do następnego katalogu w górę.

1

możesz użyć XCOPY i DELETE, to obejście, ale powinno działać?

To działałoby w wielu przypadkach, ale niestety nie mogę skopiować, a następnie usunąć źródła, ponieważ przenoszę bardzo duży zestaw plików i nie ma wystarczającej ilości miejsca na dysku, aby mieć dwie kopie na raz. Zaktualizowałem pytanie, aby to wyjaśnić. Powinienem był o tym wspomnieć wcześniej. Tom Robinson
1

Niektórzy sugerują kopiowanie + usuwanie plików źródłowych, ale przenoszenie plików nie jest tym samym, co kopiowanie + usuwanie!

Podczas korzystania z(x) kopia funkcja, typrzydziel nową przestrzeń nata sama objętość na dysku twardym. Po skopiowaniu plikówstary pliki (stare przydzielone miejsce, które było wymagane dla plików) są oznaczone jakousunięte. Osiągniesz ten sam rezultat, co użytkownik końcowy, ale przeniesienie robi coś innego i bardziej efektywne.

W ruchu pliki faktycznie zmieniają tylko niektóre rekordy wMFT (główna tabela plików). Te zmiany składają się tylko z innej ścieżki, aby użytkownik mógł zlokalizować swoje pliki. Fizycznie pliki nadal pozostają w tych samych sektorach na dysku twardym.

Jeśli nie korzystasz z xcopy lub Robocopy, co sugerowałbyś przenieść foldery? oro777
0

który napisałem na podstawie próby ljsa. Przenosi on drzewa katalogów, tak jak robi to Windows, nadpisując pliki, które już istnieją w miejscu docelowym, plikami źródłowymi i unikając metody powolnego kopiowania i wymazywania, chyba że miejsce docelowe znajduje się na innym dysku .

Jeśli Twój S.O nie jest w języku angielskim, musisz zmienić wiersz 6 tekstem używanym przez polecenie Dir, gdy znajdzie 0 plików.

moveir.batkatalog_źródłowy katalog_docelowy

@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

Powiązane pytania