†DOSとバッチとスクリプト†

コマンドライン出力の取り込み

作成開始日 2018.02.13
最終更新日 2022.05.27

外部コマンドの実行結果を、バッチ内に取り込む際によく使用されるのは;
myprog > temp.txt
のような形式で、出力を一時ファイルにリダイレクトして、バッチでそのファイルを読み込むと言う方法。しかし、これは余り美しくない。Windowsのバッチには、こうした外部出力を直接取り込むためのコマンドが用意されている。と言っても、それはループ・コマンド「for」である−−もう、この時点から何か異和感があるんだが…

一応、構文を示しておくと;

for /f "usebackq tokens=項目番号" %%変数 in (`コマンド名`) do 任意の処理
これだと何だか判らないので、具体的なサンプルを示しておく。これは、カレント・ディレクトリからパス名を除去して、最後のディレクトリ名だけを取得する処理。たとえば、カレントディレクトリが「D:\ABC\XYZ\MYWORK」ならば「MYWORK」のみを取り出す。
for /f "usebackq tokens=*" %%a in (`cd`) do set dname=%%~na

各部分の意味は;

in (`cd`) 実行するコマンド名をバッククォート「`」(逆向き引用符:back-quote)で囲んだもの。「`」で囲まれた文字列はコマンドと見なされ、その実行結果が処理の対象となる。ここではカレント・ディレクトリの表示コマンド「cd」を実行している。ちなみに;
o ファイル名の場合は直接記述【例】in(myfile.txt)
o 文字列の場合は「"」で囲む【例】in ("This is a pen.")
%%a 上記のコマンドの実行結果を入れる変数。この変数名はやや特殊であるため「%%a」を強く推奨。この例では「%%b」でも「%%x」でも構わないが、以下の「tokens=」で項目指定をする場合、ここの変数名を基準に、変数名がアルファベット順に自動的に割り当てられる。何のこっちゃだと思うが、ともかく「%%a」にしておけ、ということ。
usebackq 上記の「`」を使うよ、と言う宣言。これを指定しないと、「`」はコマンド実行の意味を持たず、単なる文字として扱われる…と言うことなんだろうか?
tokens=* 取得する項目番号を指定するもの。これは、たとえば実行結果が「ABC 12345 FF8800」などのように、スペース等で区切られた形式で出力された場合、何番目の項目が欲しいか指定するもの。「tokens=1,3」(1番目と3番目の項目が欲しい)とか、「tokens=2-4」(2番目から4番目の項目が欲しい)などのように指定する。この例では「*」=全項目取得でも問題ないが、そもそも1項目しかないので「tokens=」指定は不要。
/f 上記のtokens処理(1行を複数項目の集まりと見做し項目単位で扱う処理)を有効にするよ、と言う宣言。この例ではそもそもtokens処理を使わないので不要かと思いきや、「usebackq」指定をするには、この「/f」が必須のようだ。
for ここではループ的な処理は全くしていないので不自然な感じがするが、外部コマンドは複数行の出力をすることも珍しくない(例えばDIRコマンド)。そうした、複数行出力を1行ずつ処理するのがforコマンドと考えれば納得がいく…ではあるのだが、そもそも、外部プログラムの出力の取り込みが、独立したコマンドではなく、forループのバリエーションとして実装されているのがおかしんだよな。
%%~na 変数「%%a」の中身を分解する命令。「%%」と「a」の間に命令を挟み込む。「~n」はフルパス名からパス部分を取り去って、ファイル名もしくは最後のディレクトリ名のみを取り出す命令。この機能は通常の環境変数には使用できない。


【DOSとバッチとスクリプト目次】 【ホーム】