Windows コンソール プログラミング - バッチファイルの引数を操作する

PROGRAM

Windows コマンドプロンプトのバッチファイルにおいて、引数として受け取った値の操作方法についてまとめてみました。


バッチファイルの引数を操作する

目次

 

引数をもらってみる

バッチファイルはコマンドプロンプトから、まるでコマンドのひとつのように呼び出すことが出来ますよね。

バッチファイルでもコマンドと同様に引数を渡すことが出来ます。渡された引数は %1 から %9 までの変数として保存されます。 %0 もあるのですけど、これには実行中のバッチファイル名が保存されます。

たとえば次のような、自分自身のファイル名と、受け取った引数のうちの最初の3つを表示するバッチファイルを作成してみましょう。

@echo off

 

echo 実行ファイル: %0

echo 引数1 = %1

echo 引数2 = %2

echo 引数3 = %3

このようなバッチファイルを用意したうえで、次のように実行してみましょう。バッチファイル名は arg-test.bat としています。

arg-test.bat arg_A arg_B arg_C

実行結果は次のようになると思います。

実行ファイル: arg-test.bat

引数1 = arg_A

引数2 = arg_B

引数3 = arg_C

なお、引数として使用する際に気をつけないといけない記号があります。それは "&", "|", "(", ")" で、これらはそのままだと特別な意味として解釈されてしまいます。

これを文字列の一部として使用するためには、これらの記号の頭に "^" をつける必要があります。または、引用符を使うことでも問題なく使用できるます。

 

さて、ここでちょっとした疑問です。引用符でくくると、空白をはさんでいてもひとつとして取り扱われるのでしょうか…。さっそく実験してみます。

arg-test.bat arg_A "arg_B arg_C"

2番目の引数と3番目の引数を、引用符でくくってみました。くくったものをひとつと捕らえてくれるとすれば、2番目の引数としてそれらが一緒に表示されるはずです…。そう思いつつ実験してみると、次のようになりました。

実行ファイル: arg-test.bat

引数1 = arg_A

引数2 = "arg_B arg_C"

引数3 =

しっかりと、2番目の引数として両方の文字が現れてくれました。注意点としては、引用符も一緒に手に入ってしまうようなので、処理の際には少し気をつけなくてはいけなそうです。なお、引用符をシングルクォーテーション ( ' ) にしてみたところ、見事ばらばらでしたので、くくる場合はダブルクォーテーションが正しいようです。

 

上で、引数は %1 から %9 までの変数に保存されると書きました。

では 10 個以上の引数は受け取ることは出来ないのかというと、そんなことはありません。10 個以上の引数を取得するためには shift という命令を使用します。以下ではこの特性についてお話していきますね。

 

shift とは、与えられた引数を左へずらす、といった感じの役割を持っています。たとえば、上の実験で利用していた arg-test.bat を次のように書き換えてみましょう。

@echo off

 

rem 引数をずらしてみます。

shift

 

echo 実行ファイル: %0

echo 引数1 = %1

echo 引数2 = %2

echo 引数3 = %3

そして、いつものように引数付きで実行してみると、結果は次のようになりました。

実行ファイル: arg_A

引数1 = arg_B

引数2 = arg_C

引数3 =

このように、引数のところだけ見てもひとつ前へつめられていることが分かります。あと注意する点としては、コマンド名のところ、すなわち %0 についても、shift の対象であることが分かります。

このときもし、10 個以上の引数が渡されていたとすると、%9 に 10 個目の引数の値が保存されるという仕組みです。そしてさらに shift を繰り返すことで、11 個目、12 個目、と、渡された値を取得することが出来ます。

なお、shift した状態を元に戻す命令はないので気をつけましょう。

 

また、shift は、指定された部分以降だけを左へずらす機能も持っています。たとえば、実行ファイル名、すなわち %0 はそのままで、引数部分の %1 以降をずらしたい場合は次のようにします。

shift /1

 

なお、%0 を除く引数すべてを一度に取得したい場合は %* というものを使用します。この変数からは、引用符や空白を含めたすべての引数が渡されたそのままで、ひとつの文字列として取得されます。

たとえ shift が実行されていたとしても、この値には変化はないようでした。

 

引数を展開する

受け取った引数を利用する際に、用途に応じていろいろと変換する機能が用意されていました。この機能のことを 「パス演算子」 と呼びます。この機能は FOR ループの変数にも使用することが出来るようです。

利用方法は、変数の値を取り出すときに少し一工夫してあげるだけです。たとえば、普通なら %1 として取得するところを %~1 として取得すると、引数が引用符でくくられていた場合には、その引用符を取り除いた値として取得することが出来ます。

 

他にも、特に引数がファイル名だった場合を想定したものがたくさんあるので、それらの一覧表と、またもうひとつの表でどのような感じに変換されるか、紹介してみますね。 該当するファイルが存在しない場合でもエラーにはならず、空文字が取得されます。

%~1   基本的には %1 と同等ですけど、囲んでいる二重引用符がある場合はそれを取り除きます。
%~f1 Fix 現在のフォルダを基本として、ドライブ名も含めた絶対パスに変換します。
%~d1 Drive ドライブ名を取得します。ドライブ名が含まれない場合や、何も指定しない場合は、現在位置のドライブ名が取得できます。
%~p1 Path パスのうち、フォルダ部分のみを取得します。取得されるフォルダ部分は、引数に与えられた部分のみではなく、絶対パスから算出されます。ドライブ名は含まれず "\" から始まります。また、末尾も "\" となります。相対パス指定でルートフォルダを越えてしまった場合も "\" が取得できました。
%~n1 Name ファイル名の、名前の部分のみを取得します。"\" で終わる、すなわちディレクトリ名のみの場合や、"." から始まる拡張子名だけの場合は、空文字が取得されます。
%~x1 eXtension ファイル名の、拡張子の部分を取得します。拡張子の指定がない場合は空文字が取得されます。なお、取得される拡張子名の先頭には "." が含まれます。
%~s1 Short name 全体をショートネームに置き換えます。ショートネームとは、昔、空白を含まない 8 文字までしか指定できないころのファイルやディレクトリにつけられていた名前です。既存のファイルに対応したショートネームが取得されますが、存在しない場合はそこだけ 8 文字以上や空白を含んだ文字列のままとなります。
%~a1 Attribute 指定されたものをファイルまたはフォルダとみたてて、その属性を取得します。"\" が最後になくても、その名前のフォルダが存在した場合にはそのフォルダの属性が取得できます。また、確認した環境 (Windows Server 2003) では、ファイル名の最後に "\" をつけてみても、そのファイルの属性を取得することが出来ました。
%~t1 Time 指定されたものをファイルまたはフォルダとみたてて、その日付を取得します。細かい振る舞いは %~a のときと同じでした。
%~z1 siZe 指定されたものをファイルとみたてて、そのサイズを取得します。ディレクトリを指定すると 0 が返ってくるようです。他の細かい振る舞いは %~a のときと同じでした。
%~$PATH:1 PATH 指定したファイルが、環境変数 PATH で定義されたフォルダ内に存在するかどうかを探し、あった場合はドライブ名も含めたフルパスで取得します。PATH 環境変数に指定されていなければ、カレントディレクトリは探しません。また、みつからない場合は空文字です。なお、PATH のところをそのほかの環境変数名にしてみても、その環境変数に指定されたディレクトリ内から見つけてくれるようでした。

 

実際に使用してみると、次のような感じになりました。

なお、今度は一応、2番目の引数に対して行ってみているため、%~2 というように、"2" が指定されています。また、実行しているフォルダは C:\temp\work-folder であるとします。

修飾子 引数の値 変換後の値
%~2 test-argument test-argument
"test argument" test argument
%~f2 test.bat C:\temp\work-folder\test.bat
..\test.txt C:\temp\test.txt
%~d2 test.bat C:
D:\temp D:
%~p2 test.bat \temp\work-folder\
..\..\test.txt \
%~n2 test.bat test
%~x2 test.bat .bat
%~s2 long-filename.txtfile ファイルがある場合 C:\temp\WORK-F~1\LONG-F~1.TXT
ファイルがない場合 C:\temp\WORK-F~1\long-filename.txtfile
%~a2 test.bat --a------
%~t2 test.bat 2004/05/11 02:06
%~z2 test.bat 177
%~$PATH:2 notepad.exe C:\WINNT\system32\notepad.exe

 

これらのうちいくつかはまとめて利用することが出来るとのことでしたので、それも表に書き出しておきますね。

%~dp3 %~d3 と %~p3 の組み合わせです。フォルダ名だけでなく、ドライブ名も一緒に取得したい場合に便利です。
%~nx3 %~n3 と %~x3 の組み合わせです。ファイル名と拡張子の両方を取得したい場合に便利です。
%~dp$PATH:3 %~$PATH:3 で見つけたファイルの、ドライブ名とフォルダ名を取得します。そのファイルがどのフォルダにあったかを知りたいときに便利です。
%~ftza3 %~f3 と %~t3 と %~z3 と %~a3 の組み合わせです。dir コマンドを実行したときのような値を取得できます。

 


[ もどる ]