web-dev-qa-db-ja.com

ディレクトリツリーの内容を別のディレクトリツリーに移動するにはどうすればよいですか?

ファイルといくつかのレベルのサブディレクトリを含むディレクトリがあります。

C:\Source

C:\ Sourceの内容を次の場所に移動したいと思います。

C:\Destination

要件:

  • すべてのファイルとすべてのサブディレクトリwithinC:\ SourceDataを移動する必要があります
  • コマンドをバッチファイルで実行します
  • Powershellやその他のスクリプト言語を使用できません

試行0

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

これは完全に機能しますが、移動ではなくコピーします。非常に大きなファイルのセットを移動していて、一度に2つのファイルをコピーするのに十分なディスク領域がないため、コピーしてソースを削除することはできません。

試行1

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

これにより、C:\ Sourceディレクトリ全体C:\ Destinationに移動するため、次のようになります。

C:\Destination\Source

試行2

この質問と受け入れられた答え の助けを借りて、私は思いつきました:

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

これにより、C:\ Source内のファイルが移動しますが、サブディレクトリやその内容は移動しません。バッチファイルで使用しているため、%xではなく%% xを使用したことに注意してください。

FORの使用は有望なようですが、正しい構文を使用したかどうかはわかりません。私は何かを見逃しましたか?

試行3

Nick Dの提案に従い、名前を変更してみました。

RENAME "C:\ Source" Destination

サンプルシナリオでは、これで問題なく動作しました。残念ながら、私の実際の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.

「コマンドの構文が正しくありません」と表示されます。より複雑な宛先パスを指定しようとすると、エラーが発生します。次に例を示します。

RENAME "C:\Source" "C:\MyOtherDirectory\Destination"
RENAME "C:\Source" "MyOtherDirectory\Destination"
21
Tom Robinson

更新

コードをaに調整しました。フォルダが宛先にすでに存在するかどうかを確認します。その場合、そのフォルダ内のファイルを上に移動して(ソースディレクトリ構造の走査を続行します)、それ以外の場合は、ホールセールを移動します。

スクリプトの最後にソースフォルダーが完全に削除され、宛先にある既存のフォルダーにファイルが移動されたフォルダーが削除されます(つまり、これらのフォルダーは空になっていますが、ソースで削除されていません)。

さらに、フォルダーが空であり、宛先に既に存在するかどうかを確認します。この場合は何もしません(削除するソースフォルダーはスクリプトの最後の行に残します)。これを行わないと、「ファイル名、ディレクトリ名、またはボリュームラベルの構文が正しくありません」になります。エラー。

ふew!どうやってこれをやり遂げるか教えてください!私はこれをテストしましたが、うまく機能しているようです。

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  
12
ljs

間違いなくrobocopyを使用してください。シンプルですが、非常に便利なツールです。

robocopy /move /e sourcedir destdir

これにより、空のファイルとフォルダーを含むすべてのファイルとフォルダーが移動され、移動後に元の各ファイルが削除されます。

Robocopyがインストールされていない場合は、単体で、またはMicrosoftリソースキットの一部としてダウンロードできます。

31
DavidMWilliams

Twitterで送信されたとおり:試行3と試行1を組み合わせてみてください。名前を変更して宛先フォルダーを正しく設定してから、「宛先」を正しい場所に移動してください。

1
David Webster

XCOPYは機能するので、XCOPYとDELETEを使用できます。これは回避策ですが、機能するはずですか?

1
StuperUser

vistaでの使用

 robocopyソースの宛先/MIR

/MIR ..ディレクトリツリー全体をミラーリングします(宛先のファイルも削除します)

else

 xcopy 

もちろん、後でソースを削除する必要があります:)

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

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

PAUSE

私はこのようなバッチファイルを使用しています...

または単に呼び出す:

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

ファイルといくつかのレベルのサブディレクトリを含むディレクトリがあります。

C:\ Source

C:\ Sourceの内容を次の場所に移動したいと思います。

C:\ Destination

何か足りないのかもしれませんが、フォルダの名前を変更できませんか?

1

トピックから少し外れたかもしれませんが、それでも有用です:

ソースファイルをコピーして削除することを提案する人もいますが、ファイルを移動することはコピーして削除することと同じではありません。

(x)copy関数を使用する場合、ハードディスク上の同じボリューム新しいスペースを割り当てるを使用します。ファイルのコピー後、古いファイル(ファイルに必要であった古い割り当てられたスペース)は削除済みとしてマークされます。エンドユーザーと同じ結果が得られますが、移動は別のより効率的なことを行います。

移動ファイルは実際には[〜#〜] mft [〜#〜](マスターファイルテーブル)の一部のレコードのみを変更します。これらの変更は、ユーザーがファイルを見つけるための異なるパスのみで構成されています。物理的には、ファイルはハードディスク上の同じセクターに残っています。

1
Fluxzoal

Ufukgunの答えに応じて:

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

/ s-空のものを除いて、ディレクトリとサブディレクトリをコピーします。
/e-空のものも含めて、ディレクトリとサブディレクトリをコピーします。/S/Eと同じです。/Tの変更に使用できます。
/i-宛先が存在せず、複数のファイルをコピーする場合、宛先はディレクトリーでなければならないものと想定します。
/y-既存の宛先ファイルを上書きするかどうかを確認するプロンプトを抑制します。

別の回答で述べたように、xcopyの使用は、ファイルシステム内のポインターのみを変更するネイティブのmoveコマンドほど効率的ではない場合があります。

1
axelitus

ディレクトリとコンテンツを1レベル上に移動するだけの場合:

MOVE folder_you_wan_to_move ..

..は1つ上のディレクトリを指すことに注意してください。

0
Heber

Ljsの試みに基づいて記述したこのコードはそのままにします。Windowsと同じようにディレクトリツリーを移動し、宛先に既に存在するファイルをソース内のファイルで上書きし、宛先が別のドライブにある場合を除いて、遅いコピーと消去の方法を回避します。 。

S.Oが英語でない場合は、0ファイルが見つかったときに、Dirコマンドが使用するテキストで6行目を変更する必要があります。

movedir.batsource_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
0
marc r p

あなたができる最も簡単なことはあなたの試み2を修正することだと思います

から

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

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

接吻 ;-)

編集:これは機能していないようです。したがって、私のアドバイスは、くだらないDOSコマンドラインを捨てて、BashをシェルとしてCygwinをシェルとして使用することです! (またはcygwinバイナリをパスに追加するだけで、DOS内でmvを使用できるため、要件の状態としてシェルを変更する必要がありません)。

0
fortran

私はxxcopyというユーティリティを使用しています。それはファイルを移動でき、多くの便利なオプションがあり、次のように使用できます:

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

オプション:

  • / E空のフォルダーもすべてコピーする

  • / RCは、コピーが成功するたびにすべてのソースファイルを削除します

xxcopyの無料コピーは、次の場所から個人用にダウンロードできます。 http://www.xxcopy.com/xcpydnld.htm

0