【bat】親ディレクトリより更に上のディレクトリパスを取得する方法

bat

2つ上のディレクトリパスなど、親ディレクトリよりも上の階層のディレクトリパスを取得するバッチを作成する方法を紹介します。

関数(サブルーチン)で定義していますので、知りたい階層を自由に指定することができます。

【コピペ用】親ディレクトリより更に上のディレクトリパスを取得する方法

使用するフォルダの構成は以下の通りです。

続いてソースの全文です。

サンプルとして‘4th’フォルダから4階層上のフォルダパスを取得します。

@echo off
setlocal enabledelayedexpansion
set inDir=c:\in\1st\2nd\3rd\4th

rem %1:取得したフォルダパスをsetする変数名
rem %2:基準のフォルダパス
rem %3:基準フォルダパスから何階層上かを指定
call :loopGetDir checkDir !inDir! 4

echo 基準フォルダパス: !inDir!
echo 取得フォルダパス: !checkDir!

endlocal
pause
exist

rem /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_
rem 指定回数分'1つ上のフォルダパスを取得する関数'を呼び出す関数
rem /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_
:loopGetDir
set tmpDir=%2
for /l %%i in (1,1,%3) do (
  call :getDir !tmpDir!
)
set %1=!tmpDir!
exit /B 0

rem /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_
rem 1つ上のフォルダパスを取得する関数
rem /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_
:getDir
for /f "delims=" %%d in ('echo %1') do (
  set tmpDir=%%~dpd
  set tmpDir=!tmpDir:~0,-1!
)
exit /B 0
基準フォルダパス: c:\in\1st\2nd\3rd\4th
取得フォルダパス: c:\in

【解説】親ディレクトリより更に上のディレクトリパスを取得する方法

関数(サブルーチン)を2つ用意しています。

1つ上のフォルダパスを取得する関数

:getDir関数では引数(%1)に指定されたフォルダパスの1階層上のフォルダパスを返します。

返すといっても、batでは他のプログラミング言語のようなreturn文は用意されていません。

そのためここでは一旦tmpDirという変数に値をセットしています。このtmpDirがどこから来たかは後程説明しますので、ここではtmpDir変数に値をセットすることがreturn文の代わりと思ってください。

rem /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_
rem 1つ上のフォルダパスを取得する関数
rem /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_
:getDir
for /f "delims=" %%d in ('echo %1') do (
  set tmpDir=%%~dpd
  set tmpDir=!tmpDir:~0,-1!
)
exit /B 0

‘1つ上のフォルダパスを取得する関数’を呼び出す関数

:loopGetDir関数は引数(%3)で指定した回数分、:getDir関数を呼び出しています。

この関数の中でも:getDir関数で使用していたtmpDir変数を使用しています。なぜ同じ変数名を使用しているのかというと、batではスコープの概念が無いため、関数が違っていても、変数名が同じなら、同じ変数と認識してしまうためです。

今回はその性質を利用して疑似的なreturn文としていますが、もしメイン処理でtmpDirという変数名を使用している場合、:loopGetDir関数の結果がおかしくなってしまうため注意してください。

rem /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_
rem 指定回数分'1つ上のフォルダパスを取得する関数'を呼び出す関数
rem /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_
:loopGetDir
set tmpDir=%2
for /l %%i in (1,1,%3) do (
  call :getDir !tmpDir!
)
set %1=!tmpDir!
exit /B 0

1番目の引数(%1)で取得したフォルダパスを格納する変数名を指定しています。今回は’checkDir’と指定しましたが、任意の文字列でOKです。事前にsetで定義をする必要もありません。

3番目の引数(%3)で取得したい上の階層数を指定しています。

rem %1:取得したフォルダパスをsetする変数名
rem %2:基準のフォルダパス
rem %3:基準フォルダパスから何階層上かを指定
call :loopGetDir checkDir !inDir! 4

今回のサンプルではディレクトリパスのみ取得していますが、もしディレクトリ名を取得したい場合は、こちらの記事を参考にしていただければ、実装可能です。

【bat】ファイルパスからフォルダパスを取得する方法
batでファイルパスからファイル名、フォルダパス、フォルダ名を取得する方法を説明します。

ぜひお試しください。

コメント