【bat】バッチファイルでファイルをサイズ順にランキング出力する完全ガイド|dir・上位N件・閾値フィルタ・フォルダ容量ランキング・CSV出力まで

【bat】バッチファイルでファイルをサイズ順にランキング出力する完全ガイド|dir・上位N件・閾値フィルタ・フォルダ容量ランキング・CSV出力まで bat

「どのファイルがディスクを圧迫しているか」「大きいファイルトップ10を抽出したい」——ファイルのサイズ順ランキングはディスク管理や定期メンテナンスに欠かせません。

バッチファイルでは dir /O-S で手軽にサイズ順一覧を出力できますが、上位N件の抽出・閾値フィルタ・フォルダ別容量ランキング・CSV出力など実務で使えるパターンまで網羅して解説します。

この記事でわかること

  • dir /O-S・/OS でサイズ降順・昇順に出力する基本
  • サブフォルダを含めた全ファイルのサイズ順一覧を取得する方法
  • 上位N件(例:大きいファイルトップ10)だけを抽出する方法
  • X MB 以上のファイルだけを閾値フィルタで抽出する方法
  • フォルダ別の使用容量をランキング表示する方法
  • PowerShell でサイズ順一覧を CSV ファイルに出力する方法
スポンサーリンク

サイズ順出力の方法比較

方法 コマンド 上位N件抽出 閾値フィルタ CSV出力
dir /O-S dir /S /O-S /A:-D △(手動加工) ✕(書式固定)
for + %%~zF for /r %%F in (*) do if %%~zF gtr N ○(自由に整形)
PowerShell Get-ChildItem | Sort-Object Length -Desc ○(-First N) ○(Where-Object) ○(Export-Csv)
用途別の使い分け
手軽に全体を確認するだけなら dir /O-S が最速です。上位N件の抽出や閾値フィルタが必要なら PowerShell が簡潔に書けます。純バッチで閾値フィルタ(例:10 MB 以上)をかけるには for + %%~zF で実装します。

基本:dir でサイズ順にファイル一覧を出力する

dir オプション一覧: サイズ順出力
REM サイズの大きい順(降順)
dir /O-S /A:-D "C:\TargetFolder"

REM サイズの小さい順(昇順)
dir /OS /A:-D "C:\TargetFolder"

REM サブフォルダを含める(/S)
dir /S /O-S /A:-D "C:\TargetFolder"

REM ファイルのみ(フォルダを除外)+サイズ降順
REM /A:-D = ディレクトリ属性を持たないもの(=ファイルのみ)
dir /S /O-S /A:-D "C:\TargetFolder"
サイズ順一覧をログファイルに出力する基本バッチ
@echo off
setlocal

set TARGET_DIR=C:\TargetFolder
set LOG_DIR=C:\logs
if not exist "%LOG_DIR%" mkdir "%LOG_DIR%"

REM ロケール非依存の日付取得
for /f "tokens=2 delims==" %%A in ('wmic os get LocalDateTime /value') do set DT=%%A
set TODAY=%DT:~0,8%
set LOGFILE=%LOG_DIR%\filesize_%TODAY%.txt

echo ===== ファイルサイズ順一覧: %TARGET_DIR% ===== > "%LOGFILE%"
echo 出力日時: %DATE% %TIME% >> "%LOGFILE%"
echo. >> "%LOGFILE%"

dir /S /O-S /A:-D "%TARGET_DIR%" >> "%LOGFILE%"

echo 出力完了: %LOGFILE%
endlocal
dir /O-S の出力に含まれる情報
dir のデフォルト出力には「日付・時刻・サイズ・ファイル名」が含まれます。ただしサイズは桁区切りカンマ付き(例: 1,234,567)で数値計算には使いにくい形式です。数値として扱いたい場合は %%~zFfor ループの修飾子)かPowerShell を使います。ファイルサイズの取得・単位変換についてはファイルサイズを取得する完全ガイドも参照してください。

サイズ上位N件だけを抽出する

dir /O-S の出力からファイル行だけをカウントして上位N件で停止するバッチです。ディスク使用量の多いファイルトップ10などを素早く確認できます。

サイズ上位10件を抽出してログに出力
@echo off
setlocal enabledelayedexpansion

set TARGET_DIR=C:\TargetFolder
set TOP_N=10
set LOGFILE=C:\logs\top%TOP_N%_files.txt
if not exist "C:\logs" mkdir "C:\logs"

echo ===== サイズ上位 %TOP_N% 件: %TARGET_DIR% > "%LOGFILE%"
echo 出力日時: %DATE% %TIME% >> "%LOGFILE%"
echo. >> "%LOGFILE%"

set COUNT=0
REM dir /O-S の出力からファイル行(サイズが数字の行)を抽出
for /f "tokens=1-4*" %%A in ('dir /S /O-S /A:-D "%TARGET_DIR%"') do (
    REM ファイル行の判定: 3列目が数字(サイズ)の行
    echo %%C | findstr /r "^[0-9,]*$" >nul 2>&1
    if !errorlevel! equ 0 (
        set /a COUNT+=1
        if !COUNT! leq %TOP_N% (
            REM サイズ(%%C)とファイル名(%%D)を出力
            echo !COUNT!. %%C bytes  %%D >> "%LOGFILE%"
        )
    )
)

echo 抽出完了: 上位 %TOP_N% 件 >> "%LOGFILE%"
echo 完了: %LOGFILE%
endlocal
dir 出力のファイル行判定について
dir の出力にはファイル行の他にヘッダー・フッター・フォルダ名行が含まれます。ファイル行は「日付 時刻 サイズ ファイル名」の形式で、サイズ列が数字(カンマ区切り)のみで構成されています。findstr /r "^[0-9,]*$" でこの列を検出することでファイル行のみを抽出できます。ただし dir の出力形式はロケールや Windows バージョンで変わる場合があるため、より確実に処理するには PowerShell を使うことを推奨します。

閾値フィルタ:X MB 以上のファイルだけを抽出する

%%~zF でバイト単位のサイズを取得し、指定した閾値(例: 100 MB = 104,857,600 バイト)以上のファイルのみを出力します。ディスク圧迫の原因となる大きなファイルを特定するのに有効です。

閾値フィルタ: 100 MB 以上のファイルを一覧出力
@echo off
setlocal enabledelayedexpansion

set TARGET_DIR=C:\TargetFolder
set LOGFILE=C:\logs\large_files.txt
if not exist "C:\logs" mkdir "C:\logs"

REM 閾値: 100 MB = 104857600 バイト
set THRESHOLD=104857600

echo ===== %THRESHOLD% バイト以上のファイル: %TARGET_DIR% > "%LOGFILE%"
echo 出力日時: %DATE% %TIME% >> "%LOGFILE%"
echo. >> "%LOGFILE%"

set COUNT=0
set TOTAL=0
for /r "%TARGET_DIR%" %%F in (*) do (
    if %%~zF gtr %THRESHOLD% (
        set /a COUNT+=1
        set /a TOTAL_MB=%%~zF / 1048576
        echo !COUNT!. !TOTAL_MB! MB  %%F >> "%LOGFILE%"
    )
)

echo. >> "%LOGFILE%"
echo 対象ファイル数: %COUNT% 件 >> "%LOGFILE%"
echo 完了: %COUNT% 件 >> "%LOGFILE%"
echo 完了: %LOGFILE%
endlocal
MB・GB 閾値の換算表
1 MB = 1,048,576 バイト、10 MB = 10,485,760 バイト、100 MB = 104,857,600 バイト、1 GB = 1,073,741,824 バイトです。set /a は 32 ビット整数(最大 2,147,483,647 ≒ 2 GB)までしか扱えません。2 GB 以上のファイルを閾値にする場合は PowerShell を使ってください。ファイルサイズの条件分岐パターン全般はファイルサイズを条件分岐に活用する完全ガイドを参照してください。

フォルダ別の使用容量をランキング表示する

サブフォルダごとの合計サイズを計算して、容量が大きい順にランキング表示します。どのフォルダがディスクを使っているかを一目で把握できます。

フォルダ別容量を計算してランキング出力
@echo off
setlocal enabledelayedexpansion

set TARGET_DIR=C:\TargetFolder
set LOGFILE=C:\logs\folder_rank.txt
if not exist "C:\logs" mkdir "C:\logs"

echo ===== フォルダ別容量ランキング: %TARGET_DIR% > "%LOGFILE%"
echo 出力日時: %DATE% %TIME% >> "%LOGFILE%"
echo. >> "%LOGFILE%"

REM 直下のサブフォルダごとにバイト合計を集計
for /d %%D in ("%TARGET_DIR%\*") do (
    set FOLDER_SIZE=0
    for /r "%%D" %%F in (*) do (
        set /a FOLDER_SIZE+=%%~zF
    )
    set /a FOLDER_MB=!FOLDER_SIZE! / 1048576
    echo !FOLDER_MB! MB  %%~nxD >> "%LOGFILE%"
)

REM 結果をサイズ降順に並べ替え
echo. >> "%LOGFILE%"
echo --- ソート済み(降順)--- >> "%LOGFILE%"
sort /r "%LOGFILE%" | findstr " MB " >> "%LOGFILE%"

echo 完了: %LOGFILE%
endlocal
set /a の 2 GB 上限に注意
set /a FOLDER_SIZE+=%%~zF は 32 ビット整数演算なので合計が約 2 GB(2,147,483,647 バイト)を超えるとオーバーフローします。大きなフォルダを対象にする場合は後述の PowerShell を使ってください。

PowerShell でサイズ順ランキングを CSV に出力する

PowerShell を使うとバイト数の正確な取得・上位N件抽出・CSV出力が簡潔に書けます。Excel で分析したい場合や 2 GB を超えるファイルを扱う場合に特に有効です。

PowerShell: サイズ降順トップ20を CSV に出力
@echo off
setlocal

set TARGET_DIR=C:\TargetFolder
set CSV_FILE=C:\logs\filesize_rank.csv
if not exist "C:\logs" mkdir "C:\logs"

powershell -NoProfile -Command "
Get-ChildItem -Path '%TARGET_DIR%' -Recurse -File |
Sort-Object Length -Descending |
Select-Object -First 20 |
Select-Object Name,
    @{N='SizeMB';E={[math]::Round($_.Length/1MB,2)}},
    @{N='SizeBytes';E={$_.Length}},
    DirectoryName,
    LastWriteTime |
Export-Csv -Path '%CSV_FILE%' -Encoding UTF8 -NoTypeInformation
"

echo CSV出力完了: %CSV_FILE%
endlocal
PowerShell: フォルダ別容量ランキングを表示(2 GB 超対応)
@echo off
setlocal

set TARGET_DIR=C:\TargetFolder

powershell -NoProfile -Command "
Get-ChildItem -Path '%TARGET_DIR%' -Directory |
ForEach-Object {
    $size = (Get-ChildItem -Path $_.FullName -Recurse -File -ErrorAction SilentlyContinue |
        Measure-Object -Property Length -Sum).Sum
    [PSCustomObject]@{
        Folder = $_.Name
        SizeMB = [math]::Round($size/1MB, 1)
        SizeGB = [math]::Round($size/1GB, 3)
    }
} | Sort-Object SizeMB -Descending | Format-Table -AutoSize
"
endlocal
PowerShell の計算精度と bat の set /a の違い
PowerShell は [long](64ビット整数)または [double] で演算するため、2 GB を超えるファイルサイズも正確に扱えます。バッチの set /a は 32 ビット符号付き整数(最大 ≒ 2 GB)なので、大容量フォルダの集計には PowerShell が安全です。バッチからPowerShellを呼び出す場合は -NoProfile を付けると起動が速くなります。

まとめ

  • サイズ降順一覧: dir /S /O-S /A:-D が最も手軽
  • 上位N件抽出: PowerShell Sort-Object Length -Desc | Select-Object -First N が簡潔
  • 閾値フィルタ(純バッチ): for /r %%F in (*) do if %%~zF gtr 閾値(2 GB 未満)
  • フォルダ別容量: for /d %%D + 内側 for /r %%F で合計集計(2 GB 超は PowerShell)
  • CSV出力: PowerShell Export-Csv で Excel 分析に対応

関連記事: ファイルサイズを取得する完全ガイド(%%~zF・単位変換) / ファイルサイズを条件分岐に活用する完全ガイド / 0バイトファイルを自動削除する完全ガイド

よくある質問(FAQ)

Qdir /O-S でサブフォルダを含めると出力が多くて見づらいです。
Adir /S /O-S はサブフォルダごとにグループ分けして出力するため、フォルダをまたいだ全体ランキングにはなりません。フォルダをまたいで全ファイルをサイズ降順に並べたい場合は PowerShell の Get-ChildItem -Recurse | Sort-Object Length -Descending を使います。
Q%%~zF が 2 GB を超えるファイルで正しく動きません。
A%%~zF 自体は 2 GB 超のサイズも正しく返しますが、set /a で演算すると 32 ビット整数の上限(約 2.1 GB)でオーバーフローします。2 GB 超のファイルを比較・合計する場合は PowerShell を使うか、値を MB 単位に変換してから演算してください。
QCSV に出力したファイルが Excel で文字化けします。
APowerShell の Export-Csv -Encoding UTF8 は BOM なし UTF-8 で出力します。Excel で直接開くと BOM がないため文字化けすることがあります。-Encoding UTF8BOM(PowerShell 6 以降)か、-Encoding Default(システムのデフォルトエンコーディング、日本語環境では Shift-JIS)を試してください。
Q隠しファイル・システムファイルも含めてサイズ順に出したいです。
Adir/A:H(隠し属性)や /A:S(システム属性)を追加するか、/A(すべての属性)で全ファイルを対象にします。PowerShell では Get-ChildItem -Force で隠しファイルを含められます。ただしシステムファイルへのアクセスには管理者権限が必要な場合があります。
Q拡張子ごとにファイルサイズの合計を集計したいです。
APowerShell で Group-Object ExtensionMeasure-Object Length -Sum を組み合わせると拡張子別の合計サイズを集計できます。バッチでは for /r %%F in (*.log) do set /a TOTAL+=%%~zF のように拡張子ごとにループして合計します。0バイトファイルの自動削除と組み合わせたメンテナンス処理は0バイトファイルを自動削除する完全ガイドを参照してください。