【bat】バッチファイルでフォルダを移動する完全ガイド|move・robocopy・存在確認・スペース対策・一括移動・ドライラン・実践パターンまで徹底解説

【bat】バッチファイルでフォルダを移動する完全ガイド|move・robocopy・存在確認・スペース対策・一括移動・ドライラン・実践パターンまで徹底解説 bat

バッチファイルでフォルダを移動したい場面は多くあります。「完了済みのフォルダをアーカイブ先へ移す」「日付別に整理する」「処理前・処理後でフォルダを使い分ける」など、自動化業務の定番パターンです。Windowsバッチでは move コマンドが基本ですが、スペースを含むパスの扱い・移動先の挙動・異なるドライブへの移動など落とし穴が多く、正しく理解しないと意図しない動作になります。本記事では move の基本から、存在チェック付き移動・複数フォルダ一括移動・robocopy を使った安全移動・ドライランまで完全解説します。

この記事でわかること

  • move コマンドでフォルダを移動する基本構文
  • スペースを含むパスを正しく扱う方法
  • 移動元・移動先の存在チェック付き安全な移動パターン
  • 移動先フォルダが存在する場合・しない場合の挙動の違い
  • for /d で複数フォルダを一括移動する方法
  • robocopy /move で大量データを安全に移動する方法
  • 名前を変えながら移動する方法
  • ドライラン(実際には移動せず確認だけする)の実装方法
  • 実践例3本(日付別アーカイブ・処理済みフォルダ整理・フォルダ構造を保ったまま移動)
スポンサーリンク

1. 基本:move コマンドでフォルダを移動する

Windows バッチでフォルダを移動する基本コマンドは move です。ファイルの移動にも使えますが、フォルダの移動でも同じコマンドで動作します。

:: 基本構文
:: move 移動元フォルダ 移動先

:: 例1: C:\work\old_data を C:\archive に移動
::      → C:\archive\old_data が作られる
move "C:\work\old_data" "C:\archive"

:: 例2: 名前を変えながら移動(移動先フォルダが存在しない場合)
::      → C:\archive\backup_data という名前で作られる
move "C:\work\old_data" "C:\archive\backup_data"
移動先が「存在する」か「しない」かで動作が変わる
move "C:\src\folderA" "C:\dst\newname" の動作は移動先の状態によって異なります。
C:\dst\newname存在しない場合: folderA を newname に名前変更しながら C:\dst に移動
C:\dst\newname存在する場合: folderA を newname フォルダの中に移動
この違いを理解していないと意図しない場所にフォルダが移動します。後述のセクション2で詳しく解説します。

1-1. 同一ドライブ内と異なるドライブへの移動

移動先 内部動作 速度 注意点
同一ドライブ(例: C:\→C:\) ファイルシステムのメタデータ更新のみ 瞬時(データコピーなし) 同名フォルダが移動先にあるとエラー
異なるドライブ(例: C:\→D:\) コピー → 元フォルダ削除 データ量に依存(通常のコピー速度) 途中で失敗すると元データが削除された状態になる危険あり
@echo off
setlocal

:: ─ 同一ドライブ内の移動(高速・安全) ─────────────────────
move "C:\work\project_2024" "C:\archive\project_2024"

:: ─ 異なるドライブへの移動 ──────────────────────────────────
:: 大量データの場合は robocopy /move を使う方が安全(後述)
move "C:\work\project_2024" "D:\archive\project_2024"
異なるドライブへの移動には robocopy /move が安全
異なるドライブへの move は「コピー後に元フォルダを削除」します。コピー途中でエラーが起きると、元フォルダは削除されないまま宛先に不完全なコピーが残ります。重要データや大量ファイルを別ドライブへ移動するときは、robocopy /move(後述のセクション5)を使うとリトライ機能付きで安全に移動できます。

2. 移動元・移動先の存在チェック付き安全な移動

フォルダが存在しない状態で move を実行するとエラーになります。自動化バッチでは事前に存在チェックを行い、移動先フォルダは必要に応じて自動作成するパターンが堅牢です。

@echo off
setlocal

set SRC=C:\work\data_2024
set DST=C:\archive

:: ─ 移動元の存在チェック ──────────────────────────────────
if not exist "%SRC%\" (
    echo [ERROR] 移動元フォルダが見つかりません: %SRC%
    exit /b 1
)

:: ─ 移動先の親フォルダが存在しない場合は作成 ─────────────
if not exist "%DST%\" (
    echo [INFO] 移動先フォルダを作成します: %DST%
    mkdir "%DST%"
    if %ERRORLEVEL% neq 0 ( echo [ERROR] フォルダ作成失敗 & exit /b 1 )
)

:: ─ 移動先に同名フォルダが既に存在する場合のガード ────────
for %%F in ("%SRC%") do set FOLDER_NAME=%%~nxF
if exist "%DST%\%FOLDER_NAME%\" (
    echo [ERROR] 移動先に同名フォルダが既に存在します: %DST%\%FOLDER_NAME%
    echo [INFO] 別の移動先を指定するか、既存フォルダをリネームしてください
    exit /b 1
)

:: ─ フォルダを移動 ─────────────────────────────────────────
move "%SRC%" "%DST%"
if %ERRORLEVEL% neq 0 (
    echo [ERROR] フォルダ移動失敗: %SRC% → %DST%
    exit /b 1
)

echo [OK] フォルダを移動しました: %SRC% → %DST%\%FOLDER_NAME%
フォルダ存在確認は末尾に \ を付ける
if exist "C:\work\folder" はファイルとフォルダの両方にマッチします。フォルダのみを確認するには末尾に \ を付けて if exist "C:\work\folder\" と書きます。これによりフォルダだけに確実にマッチします。

2-1. 移動先が存在する/しない場合の動作まとめ

:: ─ ケース1: 移動先フォルダが存在しない場合 ──────────────
:: move "C:\src\A" "C:\dst\B"
:: C:\dst\B が存在しない → A を B に名前変更しながら C:\dst\ に移動
:: 結果: C:\dst\B が作られる

:: ─ ケース2: 移動先フォルダが存在する場合 ───────────────
:: move "C:\src\A" "C:\dst\B"
:: C:\dst\B が存在する → A を B フォルダの内側に移動
:: 結果: C:\dst\B\A が作られる

:: ─ ケース3: 移動先のパスが同じフォルダ名を含む場合 ──────
:: move "C:\src\A" "C:\dst\A"
:: C:\dst\A が存在しない → C:\dst\A が作られる
:: C:\dst\A が存在する → C:\dst\A\A が作られる(意図しない多重ネスト!)

3. スペースを含むフォルダパスを正しく扱う

フォルダ名やパスにスペースが含まれる場合(例: C:\Program FilesC:\My Documents)、必ずダブルクォートで囲む必要があります。囲まないとスペース以降が別の引数として解釈されエラーになります。

:: NG: スペースがあるのにダブルクォートなし → エラー
move C:\work\old data C:\archive
:: → "C:\work\old" と "data" を別々の引数として解釈するためエラー

:: OK: 移動元・移動先ともにダブルクォートで囲む
move "C:\work\old data" "C:\archive\old data"

:: 変数を使う場合も同様にダブルクォートで囲む
set SRC=C:\work\old data
set DST=C:\archive
move "%SRC%" "%DST%"
@echo off
setlocal

:: パスをあらかじめ変数に入れてダブルクォートは move 側で付ける
set SRC=C:\Users\user name\Documents\project
set DST=C:\backup

:: 移動前の存在確認(変数はダブルクォートで囲む)
if not exist "%SRC%\" (
    echo [ERROR] 見つかりません: %SRC%
    exit /b 1
)

move "%SRC%" "%DST%"
echo 移動完了: %ERRORLEVEL%

4. 複数フォルダを一括移動する(for /d ループ)

4-1. 特定パターンのフォルダをすべて移動する

@echo off
setlocal enabledelayedexpansion

set SRC_DIR=C:\work
set DST_DIR=C:\archive

if not exist "%DST_DIR%\" mkdir "%DST_DIR%"

:: SRC_DIR 直下の全サブフォルダを一括移動
set COUNT=0
for /d %%F in ("%SRC_DIR%\*") do (
    set FNAME=%%~nxF
    echo 移動中: !FNAME!
    move "%%~fF" "%DST_DIR%\" >nul 2>&1
    if !ERRORLEVEL! equ 0 (
        echo  [OK] !FNAME!
        set /a COUNT+=1
    ) else (
        echo  [FAIL] !FNAME!
    )
)

echo.
echo !COUNT! 個のフォルダを移動しました

4-2. 名前のパターンでフィルタして移動(例: 2024_ で始まるフォルダのみ)

@echo off
setlocal enabledelayedexpansion

set SRC_DIR=C:\work
set DST_DIR=C:\archive\2024

if not exist "%DST_DIR%\" mkdir "%DST_DIR%"

:: "2024_" で始まるフォルダのみを対象
for /d %%F in ("%SRC_DIR%\2024_*") do (
    echo 移動: %%~nxF
    move "%%~fF" "%DST_DIR%\" >nul 2>&1
    if !ERRORLEVEL! equ 0 (
        echo  [OK] %%~nxF → %DST_DIR%
    ) else (
        echo  [FAIL] %%~nxF
    )
)

4-3. リストファイルから移動するフォルダを指定する

@echo off
setlocal enabledelayedexpansion

:: move_list.txt: 1行1フォルダ名(コメントは # で)
:: 例:
:: # 移動対象フォルダ一覧
:: project_alpha
:: project_beta

set SRC_DIR=C:\work
set DST_DIR=C:\archive
set LIST=C:\work\move_list.txt

if not exist "%LIST%" ( echo [ERROR] リストファイルが見つかりません & exit /b 1 )
if not exist "%DST_DIR%\" mkdir "%DST_DIR%"

for /f "usebackq eol=# tokens=* delims=" %%N in ("%LIST%") do (
    set FOLDER=%%N
    if exist "%SRC_DIR%\!FOLDER!\" (
        move "%SRC_DIR%\!FOLDER!" "%DST_DIR%\" >nul 2>&1
        if !ERRORLEVEL! equ 0 (
            echo [OK] !FOLDER!
        ) else (
            echo [FAIL] !FOLDER!
        )
    ) else (
        echo [SKIP] 見つかりません: !FOLDER!
    )
)

5. robocopy /move で安全にフォルダを移動する

move コマンドは異なるドライブへの移動で途中失敗リスクがありますが、robocopy/move(ファイルのみ移動)または/move /e(フォルダごと移動)を使うとリトライ機能・詳細ログ・ドライラン付きで安全に移動できます。

コマンド 動作 使いどころ
move フォルダ 移動先 フォルダを丸ごと移動(最速) 同一ドライブ・シンプルな移動
robocopy /mov ファイルのみ移動(フォルダは残る) ファイルだけ別フォルダに移したい
robocopy /move /e ファイル+空フォルダも移動(フォルダ全体移動) 異なるドライブ・大量データ・信頼性重視
@echo off
setlocal

set SRC=C:\work\project_data
set DST=D:\archive\project_data

:: robocopy でフォルダごと移動
:: /move : ファイルをコピー後に移動元から削除
:: /e    : サブフォルダ・空フォルダも含めてコピー
:: /r:3  : 失敗時に3回リトライ
:: /w:5  : リトライ間隔5秒
:: /log  : ログをファイルに出力
robocopy "%SRC%" "%DST%" /move /e /r:3 /w:5 /log:"C:\work\move_log.txt"

:: robocopy の戻り値 0〜7 は正常(8以上がエラー)
if %ERRORLEVEL% geq 8 (
    echo [ERROR] robocopy 失敗 ^(exit code: %ERRORLEVEL%^)
    exit /b 1
)

:: コピー後に元フォルダが空になっていれば削除
for /f %%I in ('dir /b /a "%SRC%" 2^>nul ^| find /c /v ""') do set REMAINING=%%I
if %REMAINING% equ 0 (
    rd "%SRC%"
    echo [OK] 移動完了・元フォルダ削除: %SRC%
) else (
    echo [WARN] 一部ファイルが残っています: %REMAINING% 件
)
robocopy の戻り値は 0〜7 が正常
robocopy の終了コードは 0〜7 が正常範囲で、8以上 がエラーです。if %ERRORLEVEL% neq 0 でエラー判定すると、ファイルがコピーされた(戻り値1〜7)場合も全てエラー扱いになります。必ず if %ERRORLEVEL% geq 8 でエラー判定してください。詳しいフォルダコピー方法は バッチファイルでフォルダをコピーする方法完全ガイド を参照してください。

6. 名前を変えながらフォルダを移動する

フォルダを移動しながら名前も変えたい場合(例: temparchive_20250317)、move コマンドを使うのが最もシンプルです。移動先パス(フォルダ名を含む)が存在しない場合、その名前で新しく作成されます。

@echo off
setlocal

:: フォルダを移動しながら名前を変更する
:: 移動先の C:\archive\data_20250317 が存在しない場合:
::   → data_20250317 という名前で C:\archive に移動される
move "C:\work\temp" "C:\archive\data_20250317"

:: 確認
if exist "C:\archive\data_20250317\" (
    echo [OK] 移動完了: C:\archive\data_20250317
) else (
    echo [ERROR] 移動先フォルダが見つかりません
)

6-1. 日付を付けてアーカイブ移動する(名前変更 + 移動の組み合わせ)

@echo off
setlocal

set SRC=C:\work\temp
set ARCHIVE_BASE=C:\archive

:: 今日の日付を取得(YYYYMMDD形式)
for /f "tokens=2 delims==." %%D in ('wmic os get LocalDateTime /value ^| findstr LocalDateTime') do set DT=%%D
set TODAY=%DT:~0,8%

:: アーカイブ先フォルダ名 = 元フォルダ名 + 日付
for %%F in ("%SRC%") do set FNAME=%%~nxF
set DST=%ARCHIVE_BASE%\%FNAME%_%TODAY%

if not exist "%SRC%\" ( echo [ERROR] 移動元なし: %SRC% & exit /b 1 )
if exist "%DST%\" ( echo [ERROR] 同名アーカイブが既に存在: %DST% & exit /b 1 )

if not exist "%ARCHIVE_BASE%\" mkdir "%ARCHIVE_BASE%"

move "%SRC%" "%DST%"
if %ERRORLEVEL% equ 0 (
    echo [OK] アーカイブ完了: %DST%
) else (
    echo [ERROR] 移動失敗
    exit /b 1
)

フォルダ名の変更(同じ場所でリネームだけする場合)については バッチファイルでフォルダ名を変更する方法、日付付きフォルダ名の生成については バッチファイルでフォルダを作成する方法完全ガイド も参照してください。

7. ドライラン:実際には移動せず確認だけする

大量のフォルダを移動する前に「何がどこに移動されるか」を確認したいことがあります。/dry などの引数フラグを受け取り、実際の move をスキップするドライランモードを実装することで安全に事前確認できます。

@echo off
setlocal enabledelayedexpansion

:: 引数 /dry が指定された場合はドライランモード
set DRY=0
if /i "%~1"=="/dry" set DRY=1

set SRC_DIR=C:\work
set DST_DIR=C:\archive

if !DRY!==1 (
    echo ===== ドライランモード(実際には移動しません) =====
) else (
    echo ===== 移動モード =====
)

set COUNT=0
for /d %%F in ("%SRC_DIR%\*") do (
    set FNAME=%%~nxF
    if !DRY!==1 (
        echo [DRY] 移動予定: !FNAME! → %DST_DIR%\!FNAME!
    ) else (
        move "%%~fF" "%DST_DIR%\" >nul 2>&1
        if !ERRORLEVEL! equ 0 (
            echo [OK] !FNAME!
        ) else (
            echo [FAIL] !FNAME!
        )
    )
    set /a COUNT+=1
)

echo.
echo 対象: !COUNT! フォルダ
if !DRY!==1 echo ^(ドライランのため実際には移動していません。/dry なしで再実行してください^)

:: 実行例:
::   確認のみ: batch.bat /dry
::   実際に移動: batch.bat

8. よくあるエラーと対策

エラー / 症状 原因 対策
アクセスが拒否されました フォルダが別プロセスで使用中、または権限不足 ファイルを開いているアプリを終了させる。管理者権限で実行。2>&1でエラーをログに記録
ファイルが見つかりません 移動元フォルダが存在しない if exist "%SRC%\" で事前チェック
既に存在するファイルまたはディレクトリと同じ名前のファイルは作成できません 移動先に同名フォルダが存在する 移動先の存在チェック後、別名で移動するか既存フォルダを事前処理
意図しない場所に移動された(多重ネスト) 移動先に同名フォルダが存在する状態で move を実行 セクション2の存在チェック付きパターンを使う
異なるドライブへの移動が途中で失敗 move はコピー+削除なので途中失敗でデータ消失リスク robocopy /move /e に変更してリトライ機能を利用

9. 実践例3本

実践例1:完了済みプロジェクトフォルダを日付別にアーカイブする

プロジェクトフォルダに _done フラグファイルがある場合、そのフォルダをアーカイブフォルダの年月日サブフォルダに移動するパターンです。

@echo off
setlocal enabledelayedexpansion

set PROJ_DIR=C:\projects
set ARCH_DIR=C:\archive
set LOGFILE=C:\archive\archive_log.txt

:: 本日の年月フォルダを作成
for /f "tokens=2 delims==." %%D in ('wmic os get LocalDateTime /value ^| findstr LocalDateTime') do set DT=%%D
set YYYYMM=%DT:~0,6%
set TODAY=%DT:~0,8%

set MONTH_DIR=%ARCH_DIR%\%YYYYMM%
if not exist "%MONTH_DIR%\" mkdir "%MONTH_DIR%"

set MOVED=0

for /d %%P in ("%PROJ_DIR%\*") do (
    :: _done.flg ファイルがあるプロジェクトのみ対象
    if exist "%%~fP\_done.flg" (
        set PNAME=%%~nxP
        set DEST=%MONTH_DIR%\!PNAME!_%TODAY%

        :: 同名アーカイブが既に存在する場合はスキップ
        if exist "!DEST!\" (
            echo [SKIP] 既にアーカイブ済み: !PNAME!
        ) else (
            move "%%~fP" "!DEST!" >nul 2>&1
            if !ERRORLEVEL! equ 0 (
                echo [OK] アーカイブ: !PNAME! → !DEST!
                echo [%date% %time%] OK: !PNAME! >> "%LOGFILE%"
                set /a MOVED+=1
            ) else (
                echo [FAIL] !PNAME!
                echo [%date% %time%] FAIL: !PNAME! >> "%LOGFILE%"
            )
        )
    )
)

echo .
echo アーカイブ完了: !MOVED! 件 → %MONTH_DIR%

実践例2:処理前・処理中・処理後でフォルダを自動仕分けするワークフロー

バッチ処理を inbox(未処理)→ processing(処理中)→ done(完了)の3フォルダ構成で管理し、処理ステップに応じてフォルダを移動するパターンです。複数バッチが同時実行されても競合しにくい設計です。

@echo off
setlocal enabledelayedexpansion

set BASE=C:\workflow
set INBOX=%BASE%\inbox
set PROCESSING=%BASE%\processing
set DONE=%BASE%\done
set FAILED=%BASE%\failed

for %%D in ("%INBOX%" "%PROCESSING%" "%DONE%" "%FAILED%") do (
    if not exist "%%~D\" mkdir "%%~D"
)

for /d %%F in ("%INBOX%\*") do (
    set FNAME=%%~nxF

    :: inbox → processing に移動(処理開始)
    move "%%~fF" "%PROCESSING%\" >nul 2>&1
    if !ERRORLEVEL! neq 0 (
        echo [SKIP] 移動できませんでした(別プロセスが処理中の可能性): !FNAME!
    ) else (
        echo [開始] !FNAME!

        :: ─── 処理本体 ───────────────────────────────────────
        timeout /t 2 /nobreak >nul
        :: (実際の処理をここに記述)
        set PROC_RESULT=0
        :: ─────────────────────────────────────────────────────

        :: 処理結果に応じて done または failed に移動
        if !PROC_RESULT! equ 0 (
            move "%PROCESSING%\!FNAME!" "%DONE%\" >nul 2>&1
            echo [完了] !FNAME! → done
        ) else (
            move "%PROCESSING%\!FNAME!" "%FAILED%\" >nul 2>&1
            echo [失敗] !FNAME! → failed
        )
    )
)

echo 処理完了

実践例3:フォルダ構造を保ちながら別ドライブに安全移動する(robocopy版)

大量のサブフォルダを含むプロジェクトデータを別ドライブに移動する場合、robocopy /move /e + ログ出力 + 検証のパターンです。

@echo off
setlocal enabledelayedexpansion

set SRC=C:\work\large_project
set DST=D:\archive\large_project
set LOG=C:\work\logs\move_%date:~0,4%%date:~5,2%%date:~8,2%.log

if not exist "C:\work\logs\" mkdir "C:\work\logs\"

:: 移動前のファイル数とサイズを記録
for /f %%C in ('dir /s /b /a-d "%SRC%" 2^>nul ^| find /c /v ""') do set PRE_COUNT=%%C
echo [開始] ファイル数: %PRE_COUNT% 件
echo [開始] %date% %time% - ファイル数: %PRE_COUNT% >> "%LOG%"

:: robocopy で移動(/move: ファイルをコピー後削除, /e: サブフォルダ含む)
robocopy "%SRC%" "%DST%" /move /e /r:3 /w:5 /np /log+:"%LOG%"
set ROBO_ERR=%ERRORLEVEL%

if %ROBO_ERR% geq 8 (
    echo [ERROR] robocopy 失敗 ^(exit: %ROBO_ERR%^)
    echo [ERROR] exit: %ROBO_ERR% >> "%LOG%"
    exit /b 1
)

:: 移動後の宛先ファイル数を検証
for /f %%C in ('dir /s /b /a-d "%DST%" 2^>nul ^| find /c /v ""') do set POST_COUNT=%%C

if !PRE_COUNT! equ !POST_COUNT! (
    echo [OK] 検証完了: %PRE_COUNT% 件すべて移動済み
    :: 元フォルダが空なら削除
    rd /s /q "%SRC%" >nul 2>&1
    echo [OK] 元フォルダ削除完了
) else (
    echo [WARN] ファイル数不一致: 移動前 %PRE_COUNT% 件 / 移動後 !POST_COUNT! 件
    echo 元フォルダは削除されませんでした: %SRC%
    exit /b 1
)

echo ログ: %LOG%

フォルダの削除については バッチファイルでフォルダを削除する方法完全ガイド、ファイルの移動については ファイルを別フォルダに移動する方法完全ガイド も参照してください。

10. まとめ:フォルダ移動チートシート

やりたいこと コマンド例
フォルダを移動(基本) move "移動元" "移動先"
存在チェック付き移動 if not exist "%SRC%\" ( エラー ) else ( move ... )
移動先に同名がある場合の確認 if exist "%DST%\%FNAME%\" ( スキップ )
名前を変えながら移動 move "元フォルダ" "移動先\新しい名前"(移動先が存在しない場合)
複数フォルダを一括移動 for /d %%F in ("%SRC%\*") do move "%%~fF" "%DST%\"
ドライラン(確認のみ) if "%~1"=="/dry" フラグで move をスキップ
異なるドライブへ安全に移動 robocopy "%SRC%" "%DST%" /move /e /r:3 /w:5
移動後に元フォルダを削除 rd /s /q "%SRC%"(検証後に実行)

FAQ

Q移動したらフォルダが予期せずネストされました(A\A のようになった)。

Aこれは move "C:\src\A" "C:\dst\A" のように移動先に A フォルダが既に存在していた場合に発生します。move は移動先が既存フォルダの場合、その中に移動元を配置します。対策はセクション2で紹介した「移動先に同名フォルダがないかを事前チェックする」です。

Qmove でフォルダを移動しようとすると「アクセスが拒否されました」が出ます。

A主な原因は2つです。①フォルダ内のファイルが別のプロセス(エディタ・エクスプローラー等)で開かれている。②権限が不足している(管理者権限が必要なパスへの移動)。①の場合はファイルを閉じてから再実行。②の場合はバッチファイルを右クリック→「管理者として実行」してください。

Q同一ドライブ内の move は一瞬で終わりましたが、別ドライブへの move は時間がかかります。これは正常ですか?

Aはい、正常な動作です。同一ドライブ内の move はファイルシステムのメタデータを書き換えるだけでデータのコピーは行いません(瞬時)。別ドライブへの move は実際にデータをコピーしてから元を削除するため、データ量に応じた時間がかかります。大量データの場合は robocopy /move の使用を推奨します。

Qmove コマンドでフォルダを移動したとき、移動先に同名フォルダがある場合にエラーが出ます。

Amove はデフォルトで移動先フォルダの内側に配置しようとしますが、同名フォルダへのネストがWindowsの制限に引っかかるとエラーになります。まず if exist "%DST%\%FOLDER_NAME%\" で事前チェックを行い、既存フォルダがある場合はリネームしてから移動するか、別の移動先を指定してください。

Qサブフォルダを含む大量のデータを別ドライブに移動したい場合、move とrobocopy どちらが良いですか?

Arobocopy /move /e を推奨します。move は別ドライブで途中失敗するとデータが中途半端な状態になるリスクがあります。robocopy はリトライ機能(/r:3 /w:5)・詳細ログ(/log)・ドライラン(/l)が使えるため、大量データの移動に適しています。

Qmove コマンドで「フォルダーが含まれているためファイルを移動できません」というエラーが出ます。

Aこれは move にワイルドカード(*)を使った場合に、ファイルとフォルダが混在しているときに発生します。move のワイルドカードはファイルのみを対象とするため、フォルダを含む場合は for /d %%F in (...) do move のようにフォルダだけをループで処理する方法に変更してください。