こんなことを知りたい人へ向けて書いています
- Windowsバッチファイルに引数を渡して実行する方法を知りたい方
- コマンド内で呼び出したバッチファイルに引数を渡す方法を知りたい方
- その他、引数に関する操作を詳しく知りたい方(詳しくは下の目次をご覧下さい)
目次
- バッチファイルに引数を渡して実行する
- バッチファイルからバッチファイルを呼び出すときに引数を指定する
- サブルーチンに引数を引き渡す
- 10個以上の引数を使用する
- スペース以外の区切り文字に注意
- 引数から欲しい部分を抜き出す
バッチファイルに引数を渡して実行する
バッチファイルに引数を渡して実行するには大きく分けて2つの方法があります。
- コマンドプロンプト画面を開いて、バッチファイルと共に引数を指定して実行する方法
- 作成したバッチファイルの上にファイルを乗せることで、乗せたファイルを引数としてバッチファイルに引き渡す方法
の2つです。この節ではこの2つの方法について、詳しく見ていきましょう。
コマンドプロンプト画面から実行するときに引数を指定する
まずは、1つ目の「コマンドプロンプト画面からバッチファイルを実行するときに、一緒に引数を渡す方法」です。これは簡単で、実行するバッチファイル名の右側にスペースを挟んで、引数を指定してから実行します。一般的には、コマンドプロンプト画面を開いて以下のように打ち込みます。
1 |
[実行したいバッチファイル名] [第1引数] [第2引数] ... [第9引数] |
これで、[実行したいバッチファイル名]に指定したバッチファイルに[第1引数]から[第9引数]までを引き渡すことができます。ここで、通常の状態だと、引数は9つまでしか指定できないことに注意しましょう。引数を10つ以上渡す方法については、後に「10個以上の引数を指定する」の節で詳しく紹介します。
例えば、「set_arguments.bat」というバッチファイルを実行して、このファイルに引数「first」、「second」、「third」の3つを引き渡す場合は、コマンドプロンプト画面での実行コマンドは以下のようになります。
1 |
set_arguments.bat first second third |
次にバッチファイルのプログラム中で引数を参照する方法です。バッチファイルに引き渡された引数を参照するには、「%1」~「%9」を使用します。1から9までの数字は第1引数から第9引数にそれぞれ対応しています。例えば、上記の「set_arguments.bat」を実行し、3つの引数「first」、「second」、「third」を参照してコマンドプロンプト画面に書き出すには、「set_arguments.bat」の内容を以下のようにすればよいでしょう。
1 2 3 4 5 |
@echo off echo 第1引数は「%1」です。 echo 第2引数は「%2」です。 echo 第3引数は「%3」です。 |
3~5行目で第1引数~第3引数を参照し、コマンドプロンプト画面へ出力しています。これを実行すると以下の図のようになります。
これが最も基本的な引数をバッチファイルへ渡す方法です。
バッチファイルの上に乗せたファイルを引数とする方法
次は作成したバッチファイル上にファイルを乗せて実行することで、乗せたファイル名を引数としてバッチファイルへ引き渡す方法を説明します。
バッチファイルは様々な方法で実行することができ、その中の一つがファイルをバッチファイルの上に乗せることです。バッチファイルの様々な実行方法については、「バッチファイルの様々な実行方法 -コラム-」で詳しく説明しています。
例えば、バッチファイル「set_argument_1.bat」に以下のコードを書き込みます。
1 2 3 4 |
@echo off echo 引数は「%1」です。 pause |
4行目の「pause」コマンドはバッチファイルの処理を一時的に止めるコマンドであり、これがないとバッチファイルの処理が終わるとすぐにコマンドプロンプト画面が閉じてしまうため付けています。
このバッチファイルの上に「file.txt」というファイルを乗せて「set_argument_1.bat」を実行してみましょう。ドラッグ&ドロップです。
以下が実行結果です。
コマンドプロンプトに表示されている一行目が「echo」コマンドによる出力です。「%1」には乗せたファイルがフルパス名で格納されているのが分かります。注意点はファイル名だけではなく、「フルパス名」であることです。
このフルパス名からファイル名だけを切り取ったり、フォルダ名や拡張子だけを切り取ったりして使用しましょう。その詳しい方法については、「パス名の文字列を自在に切り取る -やりたいことから検索-」もしくは、この記事の最後の節「引数から欲しい部分を抜き出す」を参照してください。
この方法で複数の引数を受け取ることも可能です。その場合は、複数のファイルを選択しバッチファイルの上に乗せます(ドラッグ&ドロップ)。「set_argument_1.bat」を書き換えて、以下のようにします。名前も「set_argument_3.bat」と変更しました。
1 2 3 4 5 6 |
@echo off echo 第1引数は「%1」です。 echo 第2引数は「%2」です。 echo 第3引数は「%3」です。 pause |
3つの引数に対してコマンドプロンプト画面への出力コマンドを記述しました。このバッチファイルに3つのファイルをいっぺんにドラッグ&ドロップしてみます。
以下実行結果です。
きちんと3つのファイルのフルパス名が「%1」から「%3」に格納されているようです。
ただし、引数の順番はPC側が勝手決めますので、こちらで指定することは難しいです。引数の順番を指定する必要があるのであれば、「コマンドプロンプト画面から実行するときに引数を指定する」を採用するのが無難でしょう。
バッチファイルからバッチファイルを呼び出すときに引数を指定する
バッチファイルから別のバッチファイルを呼び出すときの引数を指定することができます。指定方法は通常の引数の指定方法と同様です。「start」や「call」コマンドで呼び出したバッチファイルの右側にスペースを挟んで引数を指定します。(「start」、「call」コマンドはバッチファイル内から他のバッチファイルを呼び出すコマンドです。詳しくは「バッチファイルからバッチファイルを呼び出す -やりたいことから検索-」を参照してください)
1 2 |
call [バッチファイル名] [第1引数] [第2引数] ... [第9引数] start [バッチファイル名] [第1引数] [第2引数] ... [第9引数] |
[バッチファイル名]には呼び出すバッチファイル名を、そしてその右側には引数を並べます。ここでも引数は9つが上限です。通常の指定方法と全く同じですね。引数の参照方法も同じです。「%1」から「%9」を使って引数を参照します。
例として、「call」コマンドでバッチファイルを呼び出し、呼び出されたバッチファイル内で引数を参照してみましょう。呼び出し元のバッチファイル「main_argument.bat」は以下のようにします。
1 2 3 4 |
@echo off rem 別のバッチファイルを呼び出す call sub_argument.bat 梅 味噌 米 |
4行目の「call」コマンドで呼び出し先のバッチファイル「sub_argument.bat」を呼び出し、引数として「梅」、「味噌」、「米」の3つを引き渡しています。呼び出し先のバッチファイル「sub_argument.bat」は以下のようにします。
1 2 3 4 5 6 7 8 |
@echo off echo ここは「sub_argument.bat」の中です。 rem 引数を参照 echo 第1引数は「%1」です。 echo 第2引数は「%2」です。 echo 第3引数は「%3」です。 |
6~8行目で第1引数から第3引数を参照して、コマンドプロンプトへ出力しています。以下は「main_argument.bat」を実行した結果です。
きちんと引数が受け渡されていることが確認できます。ここでは「call」コマンドに対する例を示しましたが、「start」コマンドに関しても全く同様の方法で引数を利用することが可能です。
サブルーチンに引数を引き渡す
サブルーチンに引数を引き渡す場合も同様です。以下のような形で書けます。サブルーチンについては、「バッチファイルでサブルーチンを使用する -やりたいことから検索-」をご覧ください。
1 2 3 4 5 6 |
rem サブルーチンの呼び出し call :[サブルーチン名] [第1引数] [第2引数] ... [第9引数] rem サブルーチンの内容 :[サブルーチン名] [「%1~9」を使って引数を参照] |
実際に例を出して説明した方が分かりやすいと思いますので、サブルーチン内で引数を参照して、コマンドプロンプト画面へ出力するバッチファイル「subroutine_argument.bat」を以下に示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@echo off rem 引数を指定してサブルーチン「test」を呼び出し call :test 111 222 333 rem ここまででメインコードを終了する exit /b rem 「test」サブルーチン :test rem 引数の参照 echo 第1引数は「%1」です。 echo 第2引数は「%2」です。 echo 第3引数は「%3」です。 |
4行目でサブルーチン「test」を呼び出しています。その時、「111」、「222」、「333」の3つの引数を指定しています。7行目はここまででメインコードを終了するコマンドです。この下からサブルーチンの内容を書いていきます。
11行目以下が「test」サブルーチンの内容です。第1引数から第3引数までをコマンドプロンプト画面へ出力しています。
以下に実行結果となります。
サブルーチンを使った引数の利用方法も基本は通常の方法とまったく同じですね。
10個以上の引数を使用する
ここまで紹介してきた方法では最大で9つまでしか引数が利用できませんでした。その理由は「%?」の?が9までしか対応していないためです。「%10」などは存在しません。
それでは、10個以上の引数は利用できないのでしょうか?安心してください。「shift」コマンドを使えば、10個以上でも引数を使用できる方法があります。
「shift」コマンドは”引数をずらし、「%?」に格納しなおす”という動作を行います。例えば、コマンドプロンプト画面で「test.bat」というバッチファイルに10個の引数を指定して実行したとします。以下のような感じです。
1 |
test.bat 1 2 3 4 5 6 7 8 9 10 |
通常の状態ならば、「%1~%9」には1~9の値が入っています。
%1 → 1
%2 → 2
…
%9 → 9
%10 → 使えない
第10引数として指定した10は受け取れませんので、使用できません。
しかし、バッチファイル内で「shift」コマンドを実行すると引数が一つだけ左にずれて「%?」に格納されます。つまり「%1~9」には2~10の値が入ることになります。
%1 → 2
%2 → 3
…
%9 → 10
そして、さらにもう一度「shift」コマンドを実行すると、
%1 → 3
%2 → 4
…
%8 → 10
%9 → 何も入っていない
となっていきます。「shift」コマンドの詳細な説明は「shift(引数をずらして格納しなおす) -コマンド別解説-」にゆずるとして、ここでは実用的な話をします。
私は10個以上の引数を扱うときは、一度すべての引数を配列(のような変数名をした変数)へ格納してしまうことをオススメします。例えば上記の例で言えば、変数「arr[1]~arr[10]」に1~10の値をはじめに入れてしまうのです。
arr[1] → 1
arr[2] → 2
…
arr[9] → 9
arr[10] → 10
これを実現するバッチファイル「shift_argument.bat」は以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
@echo off rem 引数が無ければプログラム終了 if "%1"=="" goto :eof rem 配列の要素番号になる数 set count=1 rem 配列もどき「arr[?]」にすべての引数を代入(ループ) :loop rem 引数がなくなればループから出て「:confirm」へ飛ぶ if "%1"=="" goto :confirm rem 配列に引数を代入 set arr[%count%]=%1 rem 配列番号を+1 set /a count+=1 rem 引数を一つずらす shift rem 「:loop」へ戻ってループを続ける goto loop rem 確認のための出力 :confirm echo arr[1]は「%arr[1]%」です。 echo arr[2]は「%arr[2]%」です。 echo arr[10]は「%arr[10]%」です。 |
少し長めのプログラムコードになってしまいました。上から順に説明していきましょう。
4行目は「if」コマンドを使って、引数が格納される「%1」が空でないかをチェックしています。もし空の場合は引数が設定されていないということですので、「goto :eof」によってバッチファイルを終了します。
7行目は後に配列(もどき)の要素番号に使う変数「count」の初期化です、初めに1を代入しておきます。
10行目はここから下がループ処理になっており、25行目で戻ってくるための目印です。25行目の「goto」コマンドでこの行に飛ばすようにしておくことで、ループ文となるようにしています。
13行目も再び「%1」が空であるかをチェックしています。空の場合は30行目に飛ぶようになっています。このチェックはループの中に入っているため、ループが回るたびにチェックされることになります。なぜここにこのようなチェック文があるのかは後ほど分かるでしょう。
16行目が配列(もどき)「arr[?]」に引数を代入しているところです。要素番号には変数「count」が使われており、19行目で1増加するので、ループが回るたびに1プラスされた値が入ります。
19行目が「shift」コマンドにより引数をずらしている部分です。これによって、ループが回るたびに「%1」に格納されている引数が、第1引数から第10引数まで変化していきます。そして、引数がなくなると「%1」は空になるため、13行目の空チェックでループから外に出るのです。
最後の3行は配列にきちんと値が入っているかを確認するためのコマンドプロンプト画面への出力コマンドです。第1引数、第2引数、第10引数を出力しています。
以下、実行結果です。
引数は1から10の計10個を指定して実行しています。出力結果から、引数の数が10個以上でもきちんと配列に代入されているのが分かります。
スペース以外の区切り文字に注意
ここまでの説明では引数を指定するとき、引数と引数の区切りは「スペース」を使っていました。前節で実行した「shift_argument.bat」の実行は、
1 |
shift_argument.bat 1 2 3 4 5 6 7 8 9 10 |
というように、各引数の間はスペースが入っています。これが一番自然です。
しかし、引数間の区切り文字として扱われるのはスペースだけではありません。以下のものも区切り文字として扱われます。
- スペース
- イコール「=」
- セミコロン「;」
- コンマ「,」
前節の最後に実行した「shift_argument.bat」をもう一度、区切り文字を変えて実行してみましょう。
スペース以外の3つの区切り文字で引数を区切り実行しましたが、どれも正常に引数が認識されたようです。
このように、スペース以外の区切り文字も存在しますので、たまたま引数に使用していた文字が区切り文字だった場合、意図しない場所で引数が区切られてしまう場合があるため注意が必要です。
区切り文字を区切り文字として扱わない
では、区切り文字を区切り文字として扱わず、普通の文字として扱いたい場合はどうすればよいでしょうか。この場合は、ダブルクォーテーションで囲みます。
シンプルにバッチファイル「punctuation_argument.bat」を以下のように作成して検証します。
1 2 3 |
@echo off echo 引数は「%1」です。 |
まずは、引数に「1+2=3」と指定してみます。以下の図は実行結果です。
「1+2=3」の「=」は区切り文字です。そのため、配列「%1」には「1+2」と代入されてしまっています。
次に、ダブルクォーテーションで囲って実行してみましょう。
今度は、「=3」の部分まで一つの文字として出力されました。
しかし、付けたダブルクォーテーション「”」まで余分にくっついてしまっています。これを除くのは簡単で、引数が格納されている「%1」の「%」と「1」の間に「~」を挟んで「%~1」として引数を参照しましょう。すると、ダブルクォーテーション「”」を除いた形で参照、出力してくれます。「punctuation_argument_2.bat」を以下のようにして、実行してみましょう。
1 2 3 |
@echo off echo 引数は「%~1」です。 |
無事、ダブルクォーテーションを除くことができました。
引数から欲しい部分を抜き出す
前節の最後で、「%1」を「%~1」とすると余分なダブルクォーテーションを除外することができると説明しました。
「%1」にファイルのフルパス名(例:C:\Users\ide\Desktop\バッチファイル\file.txt)が格納されているとき、「%~1」の「1」の前にアルファベットを入れることで、フルパス名から様々な部分を抜き出すことができます。
例えば、一番よく使うのがファイル名だけにする場合です。この場合は、「%~n1」と「n」を使います。実際に以下のバッチファイル「pick_filename.bat」を実行してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@echo off rem 「%1」の中身のチェック echo 【フルパス名】 echo %1 echo; rem 「%1」に入っているフルパス名からファイル名だけを取得 echo 【ファイル名】 echo %~n1 echo; pause |
4行目~6行目は「%1」に入っているファイルのフルパスを確認する部分、9行目から11行目は「%~n1」を使ってファイル名だけを抜き出している部分です。
これを実行するのですが、このバッチファイルは「file.txt」というファイルを上に乗せることで実行します。そうすることで、「%1」には「file.txt」のフルパスが格納されます。これについては、本記事の「バッチファイルの上に乗せたファイルを引数とする方法」で述べています。
以下、実行結果です。
フルパスからファイル名だけが抜き出せています。
その他にも多くの機能がありますので、一覧表で紹介します。
%~1 | ダブルクォーテーション「”」を除く |
%~f1 | フルパスすべてを表示 |
%~d1 | ドライブ名を抜き出す |
%~p1 | パスのみを抜き出す |
%~n1 | ファイル名を抜き出す |
%~x1 | 拡張子を抜き出す |
%~s1 | 短い名前にする |
%~a1 | ファイルの属性を抜き出す |
%~t1 | ファイルの日付・時刻を抜き出す |
%~z1 | ファイルのサイズを抜き出す |
個人的によく使うと思うのは、
- %n1 → ファイル名を抜き出す
- %x1 → 拡張子を抜き出す
- %t1 → ファイルの日付・時刻を抜き出す
- %z1 → ファイルのサイズを抜き出す
です。
ここでは「%1」に入っているフルパスを扱う例を紹介しましたが、「%2」、「%3」や「%?」に入っているフルパスを扱う場合は「%1」の「1」を任意の数字に変更してください。
最後に、これらの機能を複合して使う方法を紹介しておきます。例えば、「file.txt」を例にすると「file」の部分をファイル名、「.txt」の部分を拡張子と言います。
それぞれフルパス「C:\Users\ide\Desktop\バッチファイル\file.txt」から抜き出したいときは、「%~n1」と「%~x1」を使います。
では、「file.txt」を抜き出したい場合はどうでしょうか。このときは、「%~nx1」のように「n」と「x」を同時に指定すれば可能です。以下のバッチファイル「fulpass_nx.bat」を実行してみましょう。
1 2 3 4 5 6 7 |
@echo off rem ファイル名と拡張子を合わせて取得 echo %~nx1 echo; pause |
以下実行結果です。
期待通りファイル名と拡張子が合わさって出力されました。
コマンドラインで空白が含まれたファイル名の処理はクォーテーションで囲めばよいことになっていますが、ウィンドウから空白が含まれたファイル名をbatファイルにドラッグすると引数は分解されて処理されますね。抜群の対応方法はないものか?