【bat】バッチファイルのパス・ファイル名取得完全ガイド|%~f0・%~dp0・%~nx0・%~n0・%~x0・for内修飾子・引数への応用・実践パターンまで徹底解説

バッチファイルで 自身のパスやファイル名を取得するには、%0(バッチファイル自身)に 修飾子(チルダ展開)を適用します。%~f0%~dp0%~nx0 などの記法でフルパス・ディレクトリ・ファイル名・拡張子・サイズ・更新日時を取得でき、引数(%1%9)や for ループ内の変数にも同じ修飾子が使えます。

この記事でわかること

  • 修飾子(~f~d~p~n~x~nx~dp 等)の意味と使い方
  • ファイルサイズ(%~z0)・更新日時(%~t0)・属性(%~a0)の取得
  • ショートパス(8.3形式)の取得(%~s0
  • for ループ内で %%~f%%~dp%%~nx を使う方法
  • 引数(%1 等)に修飾子を適用する方法(%~f1%~dp1
  • 修飾子を組み合わせてパスを分解・再組み立てする実践テクニック
スポンサーリンク

1. パス・ファイル名取得の修飾子(チルダ展開)一覧

%0 はバッチファイル自身のパスですが、実行方法によって相対パスや省略形になることがあります。~(チルダ)に続けて修飾子を指定すると、常に確定した形式で取得できます。以下の例は C:\scripts\tools\myscript.bat というパスのバッチを実行した場合の展開結果です。

記述 展開される値 説明
%0 myscript.bat(相対パスの場合あり) バッチ自身のパス(実行方法に依存)
%~f0 C:\scripts\tools\myscript.bat フルパス(完全絶対パス)
%~d0 C: ドライブ文字のみ
%~p0 \scripts\tools\ パス部分のみ(ドライブなし・末尾 \
%~n0 myscript ファイル名のみ(拡張子なし)
%~x0 .bat 拡張子のみ(ドット付き)
%~nx0 myscript.bat ファイル名+拡張子(よく使う
%~dp0 C:\scripts\tools\ ドライブ+パス(末尾 \)(最もよく使う
%~fpnx0 C:\scripts\tools\myscript.bat 複数組み合わせ可(%~f0 と同じ)
%~z0 1024(バイト数) ファイルサイズ(バイト)
%~t0 2025/03/17 14:30 更新日時(ロケール依存)
%~a0 --a------ ファイル属性(r=読み取り専用・h=隠し・s=システム・a=アーカイブ)
%~s0 C:\SCRIPT~1\TOOLS~1\MYSCRI~1.BAT ショートパス(8.3形式・スペースなし)
@echo off

:: バッチ自身の各種情報を表示
echo フルパス     : %~f0
echo ドライブ     : %~d0
echo パス         : %~p0
echo ファイル名   : %~nx0
echo 名前のみ     : %~n0
echo 拡張子       : %~x0
echo ディレクトリ : %~dp0
echo サイズ       : %~z0 バイト
echo 更新日時     : %~t0
echo 属性         : %~a0
echo ショートパス : %~s0

2. %0 と %~f0 の違い:なぜ修飾子が必要か

%0 はバッチファイルを実行したときの指定方法がそのまま入るため、実行環境によって値が変わります。%~f0 は常にフルパスで返るため信頼性が高いです。

実行方法 %0 の値 %~f0 の値
C:\scripts\tools\myscript.bat と入力して実行 C:\scripts\tools\myscript.bat C:\scripts\tools\myscript.bat
myscript.bat(カレントから相対パス)で実行 myscript.bat C:\scripts\tools\myscript.bat
.\myscript.bat で実行 .\myscript.bat C:\scripts\tools\myscript.bat
タスクスケジューラから実行 省略形になる可能性あり C:\scripts\tools\myscript.bat(常に正確)
スクリプト内でのパス取得は常に %~f0 か %~dp0 を使う
%0 はデバッグ表示など「実行方法の確認」に使う程度にとどめ、パスを利用した処理(設定ファイルの読み込み・ログ出力先の決定等)では%~f0%~dp0 を使うのが安全です。

3. for ループ内でのファイル修飾子(%%~f・%%~dp・%%~nx 等)

for ループの変数(%%F 等)にも同じ修飾子が使えます。ループ変数の場合は %%~f%%~dp%%~nx のように%% の後に ~ を付けます(%% は1つの % に対応)。

@echo off

:: フォルダ内のファイルをループし、各ファイルの情報を表示
for %%F in (C:\work\*.txt) do (
    echo ─────────────────────────────
    echo フルパス   : %%~fF
    echo ディレクトリ: %%~dpF
    echo ファイル名 : %%~nxF
    echo 名前のみ   : %%~nF
    echo 拡張子     : %%~xF
    echo サイズ     : %%~zF バイト
    echo 更新日時   : %%~tF
)
ループ変数記述 バッチ引数での対応 説明
%%~fF %~f0 フルパス
%%~dF %~d0 ドライブ文字
%%~pF %~p0 パス部分
%%~nF %~n0 ファイル名(拡張子なし)
%%~xF %~x0 拡張子
%%~nxF %~nx0 ファイル名+拡張子
%%~dpF %~dp0 ドライブ+パス(ディレクトリ)
%%~zF %~z0 ファイルサイズ(バイト)
%%~tF %~t0 更新日時

3-1. for /r でサブフォルダも再帰的に処理する

@echo off

:: C:\work 以下の全 .txt ファイルをフルパスで出力
for /r "C:\work" %%F in (*.txt) do (
    echo %%~fF
)

:: ファイル名と親フォルダ名を組み合わせた出力
for /r "C:\work" %%F in (*.log) do (
    echo [%%~dpF] %%~nxF  ^(%%~zF bytes^)
)

4. 引数(%1〜%9)に修飾子を適用する方法

%~f00 をコマンドライン引数の番号(19)に変えると、引数として渡されたファイルパスを分解・加工できます。ドラッグ&ドロップでファイルをバッチに渡す場合や、引数でパスを指定するツール作成に便利です。

@echo off

:: 使い方: convert.bat C:\data\input.csv

if "%~1"=="" (
    echo 使い方: %~nx0 ファイルパス
    exit /b 1
)

:: 引数のパスを各パーツに分解
set INPUT_FILE=%~f1
set INPUT_DIR=%~dp1
set INPUT_NAME=%~n1
set INPUT_EXT=%~x1

echo 入力ファイル  : %INPUT_FILE%
echo 入力ディレクトリ: %INPUT_DIR%
echo ファイル名    : %INPUT_NAME%
echo 拡張子        : %INPUT_EXT%

:: 入力ファイルと同じ場所に出力ファイルを生成
set OUTPUT_FILE=%INPUT_DIR%%INPUT_NAME%_converted%INPUT_EXT%
echo 出力先: %OUTPUT_FILE%

引数の詳しい扱い方については バッチファイルで引数を渡す方法完全ガイド も参照してください。

5. 修飾子の組み合わせとパスの分解・再組み立て

複数の修飾子を組み合わせることができます。ただし実用上は %~f0%~dp0%~nx0%~n0%~x0 を個別に使い分けるのが一般的です。

@echo off
setlocal

:: 修飾子の組み合わせ例
echo dpn0 : %~dpn0
:: → C:\scripts\tools\myscript  (ドライブ+パス+名前、拡張子なし)

echo fpnx0: %~fpnx0
:: → C:\scripts\tools\myscript.bat  (%~f0 と同じ結果)

:: パス分解の実践例
:: 同じ場所・同じ名前で拡張子だけ変えたファイルを参照
set SAME_DIR_LOG=%~dpn0.log
echo ログファイル: %SAME_DIR_LOG%
:: → C:\scripts\tools\myscript.log

:: バックアップ用にバッチ名を含めたタイムスタンプフォルダを作成
for /f %%D in ('powershell -Command "Get-Date -Format yyyyMMdd_HHmmss"') do set DT=%%D
set BACKUP_DIR=%~dp0backup_%~n0_%DT%
echo バックアップ先: %BACKUP_DIR%
:: → C:\scripts\tools\backup_myscript_20250317_143022

6. ファイルサイズ・更新日時・属性を取得する(%~z・%~t・%~a)

6-1. ファイルサイズの取得(%~z)

@echo off

:: バッチ自身のサイズ
echo バッチファイルのサイズ: %~z0 バイト

:: for でファイル一覧のサイズを表示
set TOTAL=0
for %%F in (C:\work\*.log) do (
    echo %%~nxF : %%~zF bytes
    set /a TOTAL+=%%~zF
)
echo 合計サイズ: %TOTAL% バイト

:: 大きいファイルを検出
set LIMIT=1048576
for /r "C:\work" %%F in (*) do (
    if %%~zF gtr %LIMIT% (
        echo [LARGE] %%~nxF ^(%%~zF bytes^)
    )
)

6-2. 更新日時の取得(%~t)

@echo off

:: バッチ自身の更新日時
echo バッチの更新日時: %~t0

:: for でファイルの更新日時を表示
for %%F in (C:\work\*.txt) do (
    echo %%~tF  %%~nxF
)

:: 更新日時でソートした一覧(for /f + dir /od)
for /f "tokens=1,2,3 delims= " %%A in ('dir "C:\work\*.txt" /od /b') do (
    echo %%A
)

ファイルの更新日時を使った詳細な処理については ファイルの更新日時を取得する方法完全ガイド も参照してください。

6-3. ファイル属性の取得(%~a)

@echo off
setlocal enabledelayedexpansion

:: ファイル属性を取得(8文字で表示)
:: 形式: d r h s a  (d=ディレクトリ r=読み取り専用 h=隠し s=システム a=アーカイブ)
echo バッチの属性: %~a0

:: 読み取り専用ファイルのみ一覧
:: %%~aF の先頭文字が "r" なら読み取り専用
for %%F in (C:\work\*) do (
    set ATTR=%%~aF
    if "!ATTR:~0,1!"=="r" (
        echo [読み取り専用] %%~nxF
    )
)

7. ショートパス(8.3形式)の取得(%~s0・%%~sF)

%~s0 はショートパス(8.3形式)を返します。パスにスペースが含まれていてもスペースなしの形式になるため、古いツールや一部のコマンドでスペースが問題になる場合に使えます。(ただし Windows 10/11 では8.3形式の生成が無効になっている場合があります)

@echo off

:: ロングパスからショートパスを取得
echo ショートパス: %~s0
:: 例: C:\PROGRA~1\MyTool\script.bat

:: for ループ内でも使用可能
for %%F in ("C:\Program Files\*.exe") do (
    echo ロング: %%~fF
    echo ショート: %%~sfF
)
ショートパスは無効になっている環境がある
Windows の設定によっては8.3形式のショートパス生成が無効(NtfsDisable8dot3NameCreation)になっており、%~s0 がロングパスと同じ値を返すことがあります。スペース対策には、ショートパスよりダブルクォートで囲む方法が推奨されます。詳細は パスにスペースが含まれているとエラーになるときの解決策 も参照してください。

8. 最頻用パターン %~dp0 との関係

%~dp0%~d0(ドライブ)と %~p0(パス)を組み合わせた「バッチファイルが置かれているフォルダのフルパス(末尾 \ 付き)」で、バッチ開発で最も頻繁に使われる修飾子です。

@echo off

:: %~dp0 を基準にしたパス構成の例
set BASE=%~dp0
set CONFIG=%BASE%config.ini
set LOG_DIR=%BASE%logs\
set TOOL=%BASE%tools\convert.exe

echo 設定ファイル: %CONFIG%
echo ログ出力先  : %LOG_DIR%
echo ツール      : %TOOL%

:: バッチ名を使った命名規則
set LOG=%LOG_DIR%%~n0.log
echo ログファイル: %LOG%
:: → C:\tools\logs\myscript.log

%~dp0 の詳細な使い方・UNCパス対応・pushd/popd との組み合わせについては %~dp0 完全ガイド も参照してください。

9. 実践例3本

実践例1:ドラッグ&ドロップで渡されたファイルを変換して同じ場所に保存

ファイルをバッチにドラッグ&ドロップすると、%1 にそのファイルのパスが入ります。%~dp1%~n1%~x1 で分解して出力先を同じフォルダに設定します。

@echo off
setlocal

:: ドラッグ&ドロップで渡されたファイルを処理
if "%~1"=="" (
    echo ファイルをこのバッチにドラッグ&ドロップしてください
    pause
    exit /b 0
)

set INPUT=%~f1
set DIR=%~dp1
set NAME=%~n1
set EXT=%~x1

echo 処理中: %INPUT%

:: 出力ファイル名: 元のファイル名 + "_converted" + 同じ拡張子、同じフォルダ
set OUTPUT=%DIR%%NAME%_converted%EXT%
echo 出力先: %OUTPUT%

:: 処理本体(ここでは copy でサンプル)
copy "%INPUT%" "%OUTPUT%"
if %errorlevel% equ 0 (
    echo [OK] 変換完了: %OUTPUT%
) else (
    echo [ERROR] 変換失敗
    exit /b 1
)
pause

実践例2:フォルダ内のファイル情報をCSVに出力する

@echo off
setlocal enabledelayedexpansion

set TARGET_DIR=%~dp0
set OUTPUT=%~dpn0_filelist.csv

:: CSVヘッダー
echo ファイル名,サイズ(bytes),更新日時,フルパス > "%OUTPUT%"

set COUNT=0
for /r "%TARGET_DIR%" %%F in (*) do (
    :: バッチ自身と出力CSVを除外
    if /i not "%%~fF"=="%~f0" (
        if /i not "%%~fF"=="%OUTPUT%" (
            set ROW=%%~nxF,%%~zF,%%~tF,%%~fF
            echo !ROW! >> "%OUTPUT%"
            set /a COUNT+=1
        )
    )
)

echo %COUNT% 件のファイル情報を %OUTPUT% に出力しました

実践例3:バッチ自身の名前・バージョン・更新日時をログヘッダーとして記録する

@echo off
setlocal

:: バッチ自身の情報を使ってログヘッダーを自動生成
set LOG=%~dpn0.log
set SCRIPT_NAME=%~nx0
set SCRIPT_UPDATED=%~t0
set SCRIPT_SIZE=%~z0

for /f %%D in ('powershell -Command "Get-Date -Format 'yyyy-MM-dd HH:mm:ss'"') do set NOW=%%D

echo ======================================== >> "%LOG%"
echo スクリプト : %SCRIPT_NAME%              >> "%LOG%"
echo スクリプト更新日時 : %SCRIPT_UPDATED%   >> "%LOG%"
echo スクリプトサイズ : %SCRIPT_SIZE% bytes  >> "%LOG%"
echo 実行日時   : %NOW%                       >> "%LOG%"
echo 実行ユーザー: %USERNAME%                 >> "%LOG%"
echo 実行PC     : %COMPUTERNAME%              >> "%LOG%"
echo ======================================== >> "%LOG%"

:: 実際の処理
echo [%NOW%] 処理開始 >> "%LOG%"
:: ... メイン処理 ...
echo [%NOW%] 処理完了 >> "%LOG%"

echo ログ: %LOG%

10. まとめ:パス・ファイル名取得の修飾子チートシート

取得したいもの バッチ引数 for ループ変数
フルパス %~f0 %%~fF C:\tools\myscript.bat
ドライブ文字 %~d0 %%~dF C:
パス部分 %~p0 %%~pF \tools\
ファイル名(拡張子なし) %~n0 %%~nF myscript
拡張子 %~x0 %%~xF .bat
ファイル名+拡張子 %~nx0 %%~nxF myscript.bat
ディレクトリ(末尾\付き) %~dp0 %%~dpF C:\tools\最頻用
ファイルサイズ(バイト) %~z0 %%~zF 2048
更新日時 %~t0 %%~tF 2025/03/17 14:30
属性 %~a0 %%~aF --a------
ショートパス %~s0 %%~sF C:\TOOLS~1\MYSCRI~1.BAT
引数のディレクトリ %~dp1 ドロップされたファイルの場所

FAQ

Q%~dp0 と %~p0 の違いは何ですか?

A%~d0 はドライブ文字(C:)、%~p0 はドライブなしのパス部分(\tools\)です。%~dp0 はこれらを組み合わせた「ドライブ+パス(末尾 \)」で、バッチファイルが置かれているフォルダのフルパスになります。最もよく使われる組み合わせです。

Qfor ループ内で %%~nx と書くのはなぜ %% が2つあるのですか?

Aバッチファイル内では % を1文字として扱うためにエスケープが必要です。%%F と書くと実行時に %F(ループ変数)として解釈されます。修飾子は %%~nxF のように書きます。コマンドプロンプトで直接入力するときは %F%~nxF%% は不要)です。

Q%~t0 で取得した日時をファイル名に使いたいのですが、スラッシュやコロンが入ります。

A%~t02025/03/17 14:30 のような形式で返るため、そのままファイル名には使えません。PowerShell -Command "Get-Date -Format yyyyMMdd_HHmmss" でファイル名に使える形式を取得するか、文字列置換で /: を除去してください。日付フォルダの詳細は 日付と時間をファイル名に使う方法 も参照してください。

Q%~z0 でファイルサイズを取得したいのですが、0 になります。

A%~z0 はバッチファイル自身のサイズです。setlocal のみで実行中は正しく取得できます。for ループ変数でファイルサイズを取得する場合は %%~zF を使います。サイズが 0 になる場合、対象ファイルが空か存在しない可能性があります。

Q引数に渡されたパスのファイル名だけを取り出したいです。

A%~n1(拡張子なし)または %~nx1(拡張子付き)を使います。%~dp1 で引数ファイルのディレクトリ、%~x1 で拡張子も個別に取得できます。これらを組み合わせて出力ファイル名を動的に生成するパターンが実務でよく使われます。

Qネットワークパス(\\server\share)を渡した場合、%~d0 などは正しく動作しますか?

AUNCパスの場合、%~d0 は空文字(ドライブなし)になります。%~f0\\server\share\path\file.bat のように正しく返ります。%~dp0\\server\share\path\ を返します。UNCパスで cd /d "%~dp0" を使うとエラーになるため、pushd "%~dp0" を使ってください。