【bat】バッチファイルで特定の拡張子のファイルを一括移動する完全ガイド|単一・複数・サブフォルダ再帰・日付別・重複対策・ドライランまで

【bat】バッチファイルで特定の拡張子のファイルを一括移動する完全ガイド|単一・複数・サブフォルダ再帰・日付別・重複対策・ドライランまで bat

ダウンロードフォルダや作業フォルダにファイルが溜まったとき、「.jpg はimagesへ」「.csv はdataへ」と拡張子ごとに自動で振り分けしたい場面はよくあります。バッチファイルを使えば move *.jpg images\ の一行から始まり、複数拡張子の同時振り分け・サブフォルダ再帰・日付別フォルダ・重複ファイル対策まで柔軟に自動化できます。

この記事でわかること

  • 単一拡張子のファイルを移動先フォルダへ一括移動する基本
  • 複数の拡張子をそれぞれ別フォルダへ自動振り分けする方法
  • サブフォルダを含めて再帰的にファイルを移動する(for /r)
  • 実行前のドライランで対象ファイルを事前確認する方法
  • 移動先に同名ファイルがある場合の重複対策
  • 日付別フォルダへの自動振り分けパターン
スポンサーリンク

拡張子指定移動の方式比較

方式 コマンド 再帰処理 複数拡張子 推奨場面
move + ワイルドカード move *.jpg dest\ × △(複数行) カレントフォルダのみ・シンプルな移動
for in + move for %%F in (*.jpg) do × ○(条件分岐) ファイルごとに処理を加えたい場合
for /r + move for /r %%F in (*.jpg) do サブフォルダまで含めて一括移動
robocopy /MOV robocopy src dst *.jpg /MOV ◎(/E) ○(複数指定) 大量ファイル・リトライ・ログ付き移動

基本:単一拡張子ファイルを一括移動する

move *.拡張子 移動先フォルダ\ が最もシンプルな形です。移動先フォルダが存在しない場合は自動作成します。

.jpg ファイルをまとめて images フォルダへ移動
@echo off
setlocal

REM ===== 設定 =====
set SRC=C:\work
set EXT=jpg
set DEST=C:\work\images

REM 移動先フォルダが存在しなければ作成
if not exist "%DEST%" mkdir "%DEST%"

REM 対象ファイルの有無を確認
dir /b "%SRC%\*.%EXT%" >nul 2>&1
if %ERRORLEVEL% neq 0 (
    echo 対象ファイルが見つかりませんでした: *.%EXT%
    exit /b 0
)

REM 一括移動
move "%SRC%\*.%EXT%" "%DEST%\"
echo %ERRORLEVEL% == 0 ならば移動成功
echo 移動完了: *.%EXT% → %DEST%
endlocal
事前に対象ファイルの有無を確認する
dir /b "*.拡張子" >nul 2>&1 で対象ファイルが存在するか確認してから move を実行することで、ファイルがない場合の無意味なエラーメッセージを防げます。/b はファイル名のみ表示・>nul 2>&1 は出力を捨てるオプションです。

複数の拡張子をそれぞれのフォルダへ自動振り分け

画像・ドキュメント・データなど、複数の拡張子を種類ごとに別フォルダへ振り分けます。設定部分を先頭にまとめることで、拡張子を追加・変更しやすい構成にします。

3種類の拡張子を自動振り分け
@echo off
setlocal

set SRC=C:\work

REM ===== 拡張子 → フォルダのマッピング =====
REM 移動先フォルダを自動作成してから移動する

call :move_ext jpg  "%SRC%\images"
call :move_ext png  "%SRC%\images"
call :move_ext txt  "%SRC%\texts"
call :move_ext csv  "%SRC%\data"
call :move_ext xlsx "%SRC%\data"
call :move_ext pdf  "%SRC%\docs"

echo すべての振り分けが完了しました。
goto :eof

:move_ext
REM 引数: %1=拡張子, %2=移動先フォルダ
if not exist %2 mkdir %2
dir /b "%SRC%\*.%~1" >nul 2>&1
if %ERRORLEVEL% equ 0 (
    move "%SRC%\*.%~1" %2\ >nul
    echo [OK] *.%~1 → %2
) else (
    echo [SKIP] *.%~1 該当ファイルなし
)
goto :eof
:move_ext サブルーチンで拡張子追加が1行で済む
call :move_ext 拡張子 "移動先" の行を追加するだけで新しい拡張子に対応できます。拡張子ごとに仕分け処理全般を自動化したい場合はフォルダ内の全ファイルを拡張子ごとに自動仕分けする方法も参照してください。

サブフォルダを含めて再帰的に移動する(for /r)

カレントフォルダだけでなく、すべてのサブフォルダ内のファイルも含めて移動したい場合はfor /r を使います。

サブフォルダ内の .log ファイルを一か所に集める
@echo off
setlocal

set SRC=C:\work
set EXT=log
set DEST=C:\work\all_logs

if not exist "%DEST%" mkdir "%DEST%"

set COUNT=0
for /r "%SRC%" %%F in (*.%EXT%) do (
    REM 移動先フォルダ自体のファイルはスキップ
    if /i not "%%~dpF"=="%DEST%\" (
        move "%%F" "%DEST%\" >nul
        set /a COUNT+=1
        echo 移動: %%~nxF
    )
)

echo 移動完了: %COUNT% 件
endlocal
移動先フォルダ内のファイルが再度処理される問題
for /r は移動先フォルダも探索対象に含みます。すでに移動したファイルが再度処理されるのを防ぐため、if /i not "%%~dpF"=="%DEST%\" で移動先フォルダ内のファイルをスキップしています。サブフォルダ再帰処理の詳細は複数フォルダをループして一括処理する方法を参照してください。

ドライランで対象ファイルを事前確認してから移動する

本番実行前に「どのファイルが移動されるか」を確認するドライランモードを実装します。引数 dry を付けて実行すると echo(確認のみ)、引数なしで実際に移動します。

ドライランモード付き移動バッチ
@echo off
setlocal

REM 使い方:
REM   move_ext.bat       → 実際に移動
REM   move_ext.bat dry   → 対象ファイルの確認のみ(移動しない)

set SRC=C:\work
set EXT=jpg
set DEST=C:\work\images

set MODE=RUN
if /i "%1"=="dry" set MODE=DRY

echo ===== モード: %MODE% =====

for %%F in ("%SRC%\*.%EXT%") do (
    if "%MODE%"=="DRY" (
        echo [DRY] 移動対象: %%~nxF  →  %DEST%\
    ) else (
        if not exist "%DEST%" mkdir "%DEST%"
        move "%%F" "%DEST%\" >nul
        echo [MOVE] %%~nxF  →  %DEST%\
    )
)

if "%MODE%"=="DRY" (
    echo ドライラン完了。実際に移動するには引数なしで実行してください。
)
endlocal
ドライランを習慣にする
大量ファイルを移動する前にドライランで対象を確認することで、意図しないファイルの移動を防げます。ワイルドカードを使った移動の詳細はワイルドカードを使ってファイルを移動する方法も参照してください。

重複ファイル名への対応(上書き確認・リネーム)

move は移動先に同名ファイルがある場合、上書き確認ダイアログを表示します。バッチで自動化する場合は上書き許可か、タイムスタンプ付きリネームで対処します。

重複時はタイムスタンプ付きリネームして移動
@echo off
setlocal enabledelayedexpansion

set SRC=C:\work
set EXT=jpg
set DEST=C:\work\images

if not exist "%DEST%" mkdir "%DEST%"

REM wmic でタイムスタンプ取得(YYYYMMDDHHMMSS)
for /f "tokens=2 delims==" %%A in ('wmic os get LocalDateTime /value') do set DT=%%A
set TS=%DT:~0,14%

for %%F in ("%SRC%\*.%EXT%") do (
    set FNAME=%%~nF
    set FEXT=%%~xF
    set NEWNAME=!FNAME!

    REM 移動先に同名ファイルが存在する場合はタイムスタンプを付加
    if exist "%DEST%\%%~nxF" (
        set NEWNAME=!FNAME!_%TS%
        echo [RENAME] %%~nxF → !NEWNAME!!FEXT!
    )

    move "%%F" "%DEST%\!NEWNAME!!FEXT!" >nul
)

echo 移動完了
endlocal
move の上書き動作に注意
move コマンドは移動先に同名ファイルがある場合、バッチ内でも「上書きしますか?」のプロンプトを表示します。>nul で出力を捨てても確認は消えません。自動で上書きしたい場合は (echo Y) をパイプで渡すか、コピー後に元ファイルを削除する方法(copy + del)を使ってください。

日付別フォルダへの自動振り分け

ファイルを移動しながら「今日の日付」のフォルダへ自動振り分けします。毎日実行するバッチでログや出力ファイルを日付ごとに整理する場面で使えます。

.csv ファイルを YYYYMMDD フォルダへ自動振り分け
@echo off
setlocal

set SRC=C:\work\output
set BASE=C:\work\archive
set EXT=csv

REM 今日の日付を YYYYMMDD 形式で取得(wmic使用)
for /f "tokens=2 delims==" %%A in ('wmic os get LocalDateTime /value') do set DT=%%A
set TODAY=%DT:~0,8%

REM 日付フォルダを作成(例: C:\work\archive\20250428)
set DEST=%BASE%\%TODAY%
if not exist "%DEST%" mkdir "%DEST%"

REM 対象ファイルを日付フォルダへ移動
dir /b "%SRC%\*.%EXT%" >nul 2>&1
if %ERRORLEVEL% equ 0 (
    move "%SRC%\*.%EXT%" "%DEST%\" >nul
    echo [OK] *.%EXT% → %DEST%
) else (
    echo [SKIP] *.%EXT% 対象なし
)
endlocal
週別・月別フォルダへの応用
月別なら set DEST=%BASE%\%DT:~0,6%(YYYYMM)、週番号なら PowerShell で Get-Date -UFormat "%Y-W%V" を使う方法があります。日付付きフォルダへのファイル分類は定期実行バッチと組み合わせると特に効果的です。

ROBOCOPY で移動する(/MOV オプション)

大量のファイルを移動する場合や、リトライ・ログ記録が必要な場合はrobocopy /MOV が適しています。move と異なり、コピー後に元ファイルを削除する動作です。

robocopy /MOV で .bak ファイルをアーカイブへ移動
@echo off
setlocal

set SRC=C:\work
set DEST=C:\work\archive
set EXT=bak
set LOG=C:\logs\robocopy_move.log

REM /MOV  : コピー後に元ファイルを削除(移動と同じ動作)
REM /R:3  : 失敗時に3回リトライ
REM /W:5  : リトライ間隔5秒
REM /NP   : 進捗パーセント非表示
robocopy "%SRC%" "%DEST%" "*.%EXT%" /MOV /R:3 /W:5 /NP /LOG+:"%LOG%"

if %ERRORLEVEL% geq 8 (
    echo [ERROR] ROBOCOPY 移動に失敗しました
    exit /b 1
)
echo ROBOCOPY 移動完了
endlocal
robocopy の終了コードは0〜7が正常
robocopy は終了コードが 8 以上の場合のみエラーです。0〜7は正常(コピーされたファイルの状態を示す)。if %ERRORLEVEL% geq 8 でエラー判定します。詳細はバッチファイルでフォルダをコピーする方法を参照してください。

まとめ

バッチファイルで特定の拡張子ファイルを一括移動する方法をまとめます。

  • 基本: move "*.jpg" "dest\" でカレントフォルダの拡張子一括移動
  • 複数拡張子: :move_ext サブルーチンで1行追加するだけで対応
  • 再帰移動: for /r %%F in (*.ext) do move "%%F" "dest\"
  • ドライラン: 引数 dry で確認のみ実行、本番前に必ず確認
  • 重複対策: タイムスタンプ付きリネームで上書きを防ぐ
  • 日付別: wmic で日付取得 → archive\YYYYMMDD\ に自動振り分け
  • 大量ファイル: robocopy /MOV でリトライ付き安定移動

関連記事: ファイルを別フォルダに移動する方法完全ガイド / ワイルドカードを使ってファイルを移動する方法 / フォルダ内の全ファイルを拡張子ごとに自動仕分けする方法

よくある質問(FAQ)

Qmove *.jpg とするとファイルが見つかりませんと言われます。
Aカレントディレクトリに .jpg ファイルが存在しないか、バッチのカレントディレクトリが想定と異なる場合に起こります。バッチを別のフォルダから実行している場合は、先頭に cd /d "%~dp0" を追加してバッチファイルと同じフォルダに移動するか、move "%SRC%\*.jpg" "%DEST%\" のように絶対パスで指定してください。
Q拡張子を大文字・小文字両方に対応させたいです(.JPG と .jpg)。
AWindowsのファイルシステム(NTFS)は大文字小文字を区別しません。move "*.jpg" と書くだけで .JPG.Jpg.jpg のすべてが対象になります。ただし for %%F in (*.jpg) do も同様に大文字小文字を区別しないので特別な対応は不要です。
Qファイル名にスペースが含まれていると移動できません。
Aパスやファイル名はダブルクォートで囲むことで解決します。move "%%F" "%DEST%\" のように移動元・移動先の両方をダブルクォートで囲んでください。move *.jpg images のようにクォートなしの場合、スペース含みのパスはエラーになります。
Q隠しファイルや読み取り専用ファイルも移動したいです。
A通常の move は隠し属性や読み取り専用属性のファイルも移動できます。ただし読み取り専用ファイルを移動先で上書きする場合はエラーになります。事前に attrib -r "%%F" で読み取り専用属性を解除するか、robocopy /MOV /A-:R で属性を変更しながら移動する方法もあります。
Q特定の拡張子を除いたすべてのファイルを移動したいです。
Amove コマンド単体では除外指定ができません。for %%F in ("*") do でループしながら if /i not "%%~xF"==".txt" で除外したい拡張子をスキップする方法が一般的です。または robocopy /MOV /XF "*.txt" で特定拡張子を除外して移動することもできます。