バッチファイルでフォルダをまるごとコピーしたいとき、Windows には xcopy と robocopy の2つの強力なコマンドがあります。xcopy は手軽でシンプル、robocopy は差分コピー・ミラーリング・ログ記録など運用向け機能が豊富です。本記事では用途別に使い分けられるよう、両コマンドの実践パターンを体系的に解説します。
この記事でできること
xcopyでサブフォルダ・隠しファイルも含めてフォルダをまるごとコピー- 除外リストを使って不要なファイルを除いてコピー
robocopyでフォルダ間の差分のみを高速にコピーrobocopy /MIRでミラーリング(移動先を完全に一致させる)- ドライランで実行前に対象ファイルを確認
- 日次バックアップ・複数フォルダ一括コピー・差分同期の実践例3本と落とし穴・FAQ も解説
xcopy と robocopy の比較
どちらを使うか迷ったらこの表を参考にしてください。
| 機能 | xcopy | robocopy |
|---|---|---|
| サブフォルダの再帰コピー | ○ /E | ○ /S または /E |
| 差分のみコピー(更新分だけ) | △ /D(日付比較) | ◎ デフォルト動作 |
| ミラーリング(削除ファイルも同期) | × | ◎ /MIR |
| 除外リスト | ○ /EXCLUDE:file | ◎ /XF /XD(ワイルドカード対応) |
| ログファイル記録 | △ リダイレクト | ◎ /LOG /LOG+ /TS /FP |
| リトライ機能 | × | ○ /R /W |
| ドライラン(一覧表示のみ) | × | ○ /L |
| 終了コードの扱い | シンプル(0=成功) | 複雑(0〜7=成功、8以上=失敗) |
シンプルな一回限りのコピーや、特定のファイルパターンに対応するなら
xcopy。定期バックアップ・差分同期・ミラーリング・ログ記録が必要なら robocopy。
方法1: xcopy でフォルダをまるごとコピー
xcopy の基本構文は xcopy "コピー元" "コピー先" オプション です。フォルダ全体(サブフォルダ含む)をコピーするときは /E /I /H /Y の4オプションをセットで使います。
フォルダをまるごとコピー(基本)
@echo off
setlocal
set "SRC=C:\work\project"
set "DST=D:\backup\project"
xcopy "%SRC%" "%DST%" /E /I /H /Y
if errorlevel 1 (
echo [エラー] xcopy が失敗しました。
exit /b 1
)
echo コピー完了: %DST%
endlocal
| オプション | 意味 |
|---|---|
/E |
空フォルダも含めてすべてのサブフォルダを再帰コピー |
/I |
コピー先がフォルダであると仮定(存在しない場合の誤認識を防ぐ) |
/H |
隠しファイル・システムファイルもコピー |
/Y |
上書き確認をスキップ(自動上書き) |
/S |
空フォルダ以外のサブフォルダを再帰コピー(/E の代替) |
/D |
コピー元がコピー先より新しい場合のみコピー(差分コピー) |
/C |
エラーが発生しても処理を継続 |
フォルダの中身のみコピー(フォルダ自体は作らない)
@echo off setlocal set "SRC=C:\work\src" set "DST=C:\work\dst" rem "SRC\*" で中身のみコピー(SRC フォルダ自体は作成しない) xcopy "%SRC%\*" "%DST%" /E /I /H /Y echo 完了 endlocal
方法2: xcopy で除外リスト・差分コピー
除外リストでコピー不要なファイルを除く
/EXCLUDE:ファイル名 に除外パターンを書いたテキストファイルを指定します。パターンは1行1エントリで、部分一致です。
@echo off
setlocal
rem 除外リストファイルを作成
set "EXCL=%TEMP%\xcopy_exclude.txt"
(
echo .git
echo .svn
echo node_modules
echo Thumbs.db
echo .DS_Store
echo *.tmp
echo *.log
) > "%EXCL%"
xcopy "C:\project" "D:\backup\project" /E /I /H /Y /EXCLUDE:"%EXCL%"
del "%EXCL%"
echo コピー完了(除外リスト適用)
endlocal
差分コピー(更新されたファイルのみコピー)
/D オプションを付けると、コピー元ファイルの更新日時がコピー先より新しい場合のみコピーします。
@echo off setlocal rem /D: 更新日時がコピー先より新しいファイルのみコピー xcopy "C:\work" "D:\backup\work" /E /I /H /Y /D echo 差分コピー完了 endlocal
方法3: robocopy でフォルダをコピー
robocopy の基本構文は robocopy "コピー元" "コピー先" [ファイルパターン] [オプション] です。デフォルトでサブフォルダを再帰コピーし、差分のみをコピーします。
フォルダをまるごとコピー(基本)
@echo off
setlocal
set "SRC=C:\work\project"
set "DST=D:\backup\project"
rem /E: 空フォルダも含めて再帰コピー
rem /COPYALL: タイムスタンプ・属性・ACL もコピー
rem /R:3: エラー時に最大3回リトライ
rem /W:5: リトライ間隔5秒
rem /MT:8: 8スレッドで並列コピー(大量ファイル・ネットワーク越しに有効)
robocopy "%SRC%" "%DST%" /E /COPYALL /R:3 /W:5 /MT:8
rem robocopy 終了コード: 8以上がエラー
if errorlevel 8 (
echo [エラー] robocopy が失敗しました。終了コード: %ERRORLEVEL%
exit /b 1
)
echo コピー完了: %DST%
endlocal
特定のファイルパターンのみコピー
@echo off setlocal rem *.csv と *.xlsx のみコピー(スペース区切りで複数指定可) robocopy "C:\data" "D:\data_backup" *.csv *.xlsx /E /R:1 /W:1 echo 完了 endlocal
方法4: robocopy /MIR でミラーリング
/MIR オプションはコピー元にないファイルをコピー先から削除し、コピー元と完全に一致した状態にします。定期バックアップや本番→ステージング同期などに使います。
@echo off
setlocal
set "SRC=C:\web\html"
set "DST=D:\backup\html"
rem /MIR: ミラーリング(削除も含めて完全同期)
rem /LOG+: ログを追記
rem /NJH /NJS: ヘッダー・サマリー非表示
robocopy "%SRC%" "%DST%" /MIR /R:3 /W:5 /LOG+:"C:\logs\mirror.log" /NJH /NJS
if errorlevel 8 (
echo [エラー] ミラーリング失敗
exit /b 1
)
echo ミラーリング完了
endlocal
/MIR はコピー元に存在しないファイル・フォルダをコピー先から削除します。誤ったパスを指定すると大切なファイルが消えます。必ず /L(ドライラン)で対象を確認してから実行してください。
方法5: ドライランで実行前確認・ログ記録
/L オプションでコピーは実行せず対象ファイルの一覧だけを表示します。大量ファイルのコピーや /MIR 実行前に必ず使いましょう。
ドライラン(一覧表示のみ)
@echo off rem /L: ドライラン(実際にはコピーしない) robocopy "C:\src" "D:\dst" /E /L echo 上記がコピー対象です(実際にはコピーしていません)
ドライラン結果をファイルに出力して確認後に実行
@echo off
setlocal
set "SRC=C:\work\data"
set "DST=D:\backup\data"
set "DRY_LOG=C:\logs\dry_run.log"
rem ドライラン → ログに出力
robocopy "%SRC%" "%DST%" /E /L /LOG:"%DRY_LOG%"
echo ドライラン結果: %DRY_LOG%
rem 確認後に実際のコピー実行
set /p CONFIRM=上記内容でコピーを実行しますか? [Y/N]:
if /i not "%CONFIRM%"=="Y" (
echo キャンセルしました。
goto END
)
robocopy "%SRC%" "%DST%" /E /COPYALL /R:3 /W:5 /LOG+:"%DRY_LOG%"
echo コピー完了
:END
endlocal
robocopy の全オプションの詳細は bat の robocopy 完全ガイドも合わせて参照してください。
実践例A: 日次バックアップ(日付フォルダ・世代管理)
毎日実行して日付フォルダにバックアップを作成し、古いバックアップを自動削除する世代管理パターンです。
@echo off
setlocal
set "SRC=C:\work\project"
set "BACKUP_BASE=D:\backup\daily"
set "LOG_DIR=D:\backup\logs"
if not exist "%BACKUP_BASE%" mkdir "%BACKUP_BASE%"
if not exist "%LOG_DIR%" mkdir "%LOG_DIR%"
rem 今日の日付を ISO 形式で取得
for /f "usebackq tokens=*" %%D in (`powershell -NoProfile -Command "Get-Date -Format 'yyyyMMdd'"`) do set "TODAY=%%D"
set "DST=%BACKUP_BASE%\%TODAY%"
set "LOG=%LOG_DIR%\backup_%TODAY%.log"
rem 当日のバックアップが既にあればスキップ
if exist "%DST%" (
echo 本日のバックアップは既に存在します: %DST%
goto END
)
rem バックアップ実行
robocopy "%SRC%" "%DST%" /E /COPYALL /R:3 /W:5 /LOG:"%LOG%"
if errorlevel 8 (
echo [エラー] バックアップ失敗 ログ: %LOG%
exit /b 1
)
echo バックアップ完了: %DST%
rem 7日以上前のバックアップフォルダを削除(世代管理)
rem forfiles /d -7: 7日前以上の項目を対象
rem @isdir==TRUE: フォルダのみ対象(ファイルは除外)
forfiles /p "%BACKUP_BASE%" /d -7 /c "cmd /c if @isdir==TRUE rd /s /q @path" >nul 2>&1
:END
endlocal
実践例B: 複数フォルダを一括コピー
コピー元・コピー先のペアをリスト化し、for /f でループして一括コピーします。設定ファイルで対象を管理できるため、追加・変更が容易です。
@echo off
setlocal enabledelayedexpansion
set "COPY_LIST=%~dp0copy_list.txt"
set "LOG=C:\logs\bulk_copy.log"
if not exist "%LOG%" (
if not exist "C:\logs" mkdir "C:\logs"
)
rem タイムスタンプ取得
for /f "usebackq tokens=*" %%T in (`powershell -NoProfile -Command "Get-Date -Format 'yyyy-MM-dd HH:mm:ss'"`) do set "TS=%%T"
echo !TS! ===== 一括コピー開始 ===== >> "%LOG%"
rem copy_list.txt の書式: コピー元タブコピー先(1行1ペア)
for /f "usebackq tokens=1,2 delims= " %%A in ("%COPY_LIST%") do (
echo !TS! コピー: %%A -^> %%B >> "%LOG%"
robocopy "%%A" "%%B" /E /R:1 /W:1 /NJH /NJS /LOG+:"%LOG%"
if errorlevel 8 (
echo !TS! [エラー] %%A >> "%LOG%"
) else (
echo !TS! [OK] %%A >> "%LOG%"
)
)
echo !TS! ===== 完了 ===== >> "%LOG%"
echo 一括コピー完了。ログ: %LOG%
endlocal
copy_list.txt の書式(タブ区切り):
C:\work\project1 D:\backup\project1 C:\work\project2 D:\backup\project2 C:\data\reports E:\archive\reports
実践例C: 特定の拡張子・除外パターンを指定して差分同期
本番フォルダと同期フォルダを差分のみ同期し、.git・node_modules・ログファイルを除外するパターンです。
@echo off
setlocal
set "SRC=C:\dev\webapp"
set "DST=D:\deploy\webapp"
set "LOG=C:\logs\sync.log"
rem /XD: 除外フォルダ(ワイルドカード可、スペース区切りで複数指定)
rem /XF: 除外ファイル(ワイルドカード可)
rem /FFT: ファイルシステムの時刻精度を 2秒に緩める(FAT/NAS との時刻差吸収に有効)
rem /Z: 再起動可能モード(ネットワーク切断等で中断しても途中から再開可能)
robocopy "%SRC%" "%DST%" /E /XD ".git" "node_modules" ".next" /XF "*.log" "*.tmp" "*.map" ^
/R:3 /W:5 /FFT /Z /LOG+:"%LOG%" /TS /NJH
if errorlevel 8 (
echo [エラー] 同期失敗 ログ: %LOG%
exit /b 1
)
echo 差分同期完了: %DST%
endlocal
ワイルドカードを使ったファイルの一括移動については bat でワイルドカードを使ってファイルを移動する方法完全ガイドも合わせてご覧ください。
よくある落とし穴
落とし穴1: コピー先パスの末尾スラッシュの有無で動作が変わる
xcopy でコピー先が存在しない場合、末尾に \ がないと「ファイルかフォルダか」を聞いてくる場合があります。/I オプションを付けるか、末尾に \ を付けることで解決します。
rem NG: フォルダかファイルか聞かれることがある xcopy "C:\src" "D:\dst_new" rem OK: /I で「コピー先はフォルダ」と明示 xcopy "C:\src" "D:\dst_new" /E /I /H /Y rem OK: 末尾に \ を付けることでも対応可 xcopy "C:\src" "D:\dst_new\" /E /H /Y
落とし穴2: robocopy /MIR はコピー先の既存ファイルを削除する
/MIR はコピー元に存在しないファイルをコピー先から削除します。バックアップ先を別のフォルダも使っている場合、そのファイルが消えます。必ず /L でドライランを先に実行してください。
rem 必ず先にドライランで確認 robocopy "C:\src" "D:\dst" /MIR /L rem 確認後に実行 robocopy "C:\src" "D:\dst" /MIR /R:3 /W:5
落とし穴3: robocopy の終了コードは 0 以外でも成功
robocopy は成功時でもコピー件数に応じて終了コード 1〜7 を返します。if errorlevel 1 で失敗を判定すると成功でもエラー扱いになります。if errorlevel 8 以上を失敗と判定してください。
robocopy "%SRC%" "%DST%" /E
rem NG: errorlevel 1 では成功でもエラー扱いになる
rem if errorlevel 1 echo エラー
rem OK: 8以上がエラー
if errorlevel 8 (
echo [エラー] 終了コード: %ERRORLEVEL%
)
落とし穴4: xcopy はパスにスペースがあるとダブルクォートが必須
コピー元・コピー先のパスにスペースが含まれる場合、ダブルクォートで囲まないと引数が途中で切れてエラーになります。
rem NG: スペースのあるパスが途中で切れる xcopy C:\My Documents D:\backup /E /I /Y rem OK: ダブルクォートで囲む xcopy "C:\My Documents" "D:\backup" /E /I /H /Y
落とし穴5: xcopy /EXCLUDE に絶対パスが必要な場合がある
xcopy /EXCLUDE:ファイル の除外リストファイルは相対パスで動作しないことがあります。%TEMP% や %~dp0 を使って絶対パスで指定してください。
@echo off rem NG: 相対パスは動作しないことがある rem xcopy "C:\src" "D:\dst" /E /I /Y /EXCLUDE:exclude.txt rem OK: 絶対パスで指定 xcopy "C:\src" "D:\dst" /E /I /H /Y /EXCLUDE:"%~dp0exclude.txt"
よくある質問(FAQ)
同一ドライブ内の小ファイル多数のケースでは速度差はほぼありません。ネットワーク越しや大ファイルでは robocopy /MT(マルチスレッド)がxcopy より大幅に高速になります。
rem /MT: マルチスレッド有効化(/MT のみで 8スレッド、/MT:N で N スレッド指定、最大 128) robocopy "C:\src" "D:\dst" /E /MT:8 rem ネットワーク越し・別ドライブの大量ファイル移動で特に効果的 rem ※ /MT 使用時は /LOG と組み合わせると出力が混在するため /NP 推奨 robocopy "\\server\share" "D:\local" /E /MT:8 /NP /NJH /NJS
robocopy はデフォルトでサマリーを出力します。/LOG でファイルに保存、/NJH /NJS でサマリーを抑制できます。
rem サマリーをログファイルに保存 robocopy "C:\src" "D:\dst" /E /LOG:"C:\logs\copy_result.log" rem ログからサマリー部分を表示 findstr /i "files dirs" "C:\logs\copy_result.log"
コピー前に if exist でフォルダの存在確認を入れましょう。
@echo off
setlocal
set "SRC=C:\work\data"
if not exist "%SRC%" (
echo [エラー] コピー元フォルダが存在しません: %SRC%
exit /b 1
)
robocopy "%SRC%" "D:\backup" /E
endlocal
robocopy /MOV(ファイルのみ削除)または /MOVE(フォルダも削除)を使います。
rem /MOV: コピー後にファイルを削除(フォルダは残る) robocopy "C:\src" "D:\dst" /E /MOV rem /MOVE: コピー後にファイルもフォルダも削除 robocopy "C:\src" "D:\dst" /E /MOVE
copy コマンドはファイル単体のコピーのみで、フォルダ(サブフォルダ含む)のコピーはできません。フォルダをコピーするには xcopy か robocopy を使ってください。なお xcopy /S /E はサブフォルダも含めてコピーします。
まとめ
| 目的 | 推奨コマンド | ポイント |
|---|---|---|
| シンプルなフォルダコピー | xcopy /E /I /H /Y | 軽量・扱いやすい。終了コード 0 が成功 |
| 特定ファイルを除外してコピー | xcopy /EXCLUDE:file または robocopy /XF /XD | xcopy は除外ファイルに絶対パス推奨 |
| 差分のみ高速コピー | robocopy(デフォルト差分) | xcopy /D より高精度・高速 |
| ミラーリング(削除も同期) | robocopy /MIR | 必ずドライラン /L で確認してから実行 |
| マルチスレッドで高速コピー | robocopy /MT:8 | ネットワーク越し・大量ファイルに効果的 |
| 詳細ログ付きコピー | robocopy /LOG+ /TS /FP | 終了コード 8以上をエラー判定 |
一回限りのコピーなら xcopy、定期バックアップ・差分同期・ミラーリングには robocopy を使い分けるのが基本です。robocopy /MIR は強力な分、誤操作でファイルが消えるリスクもあるため、必ずドライランで確認する習慣をつけましょう。
フォルダ間の移動ログ管理については bat でフォルダ間移動の履歴を残す方法完全ガイドを、robocopy の詳細オプションは bat の robocopy 完全ガイドも合わせてご覧ください。
