まくまくWindowsノート
バッチファイルでコマンドの実行結果を変数に格納する
2021-02-01

コマンド結果の取得

Linux では、コマンドの実行結果を変数に取得するためにバッククォートを使えます。

# Linux の場合
HOGE=`command`

Windows のバッチファイルで同じようなことをするには、ちょっと面倒ですが、FOR コマンドを使って以下のように記述しなければいけません。 この例では、ver コマンドで取得した Windows のバージョン文字列を変数 HOGE に格納しています。

@echo off
setlocal
for /f "usebackq delims=" %%A in (`ver`) do set HOGE=%%A
echo %HOGE%

実行結果

Microsoft Windows [Version 10.0.18363.1256]

FOR ループに /f "usebackq" オプションを指定することで、バッククォートで囲まれた文字列がコマンドとして解釈されるようになります。 さらに、結果を 1 行単位で取得するために、デリミタを無効にする delims= オプションを指定しています。 デリミタを無効にしないと、結果がスペースで分割されてしまい、変数 HOGE に先頭のトークンである Microsoft しか格納されません。

FOR ループによってコマンドの実行結果が 1 行ずつ変数 HOGE に代入されていくので、結果として HOGE の値はコマンドの最終行になることに注意してください。 上記のように、コマンドの出力がもともと 1 行だけの場合は気にする必要はありませんが。

もう少し高度な使い方

複数のコマンドをパイプで繋ぐ

コマンドの出力をパイプで別のコマンドにつないでフィルタしたい場合は、| ではなく ^| を使います。

for /f "usebackq delims=" %%A in (`コマンド1 ^| コマンド2`) do set HOGE=%%A
echo %HOGE%

よくあるのは、コマンドの実行結果を findstr でフィルタするというものでしょうか(Linux の grep に相当します)。 次の例では、dir /b の結果から、share を含む行を変数 HOGE に格納しています。

for /f "usebackq delims=" %%A in (`dir /b ^| findstr share`) do set HOGE=%%A
echo %HOGE%

上記は本当は dir /b *share* とするだけでよいんですけどね^^;

変数に格納した値を加工して取り出す

これは FOR の使い方ではないですが、変数の値を参照するときに特殊な構文を使用すると、変数の内容を加工しつつ取り出すことができます。 例えば、%DATE% の内容を参照するときに、次のような感じで内容を置換できます。

  • echo %DATE%2021/02/01(そのまま参照した場合)
  • echo %DATE:~5%02/01(5文字目以降を抽出)
  • echo %DATE:~-2%01(末尾の2文字を抽出)
  • echo %DATE:~0,-3%2021/02(末尾の3文字を削除)
  • echo %DATE:02=XX%2XX1/XX/01(すべての 02 を XX に置換)

詳しくは set /? でヘルプを参照してください。

次の例では、ver コマンドによって取得した Windows バージョン文字列から、soft という文字を削除(空文字列に置換)して表示しています。

@echo off
setlocal
for /f "usebackq delims=" %%A in (`ver`) do set HOGE=%%A
echo %HOGE%
echo %HOGE:soft=%

実行結果

Microsoft Windows [Version 10.0.18363.1256]
Micro Windows [Version 10.0.18363.1256]

これくらいの処理であれば、バッチファイルだけでも十分記述できます。

参考

Windows の FOR ループは他にもいろいろな使い方があります。 下記の記事を参考にしてください。

2021-02-01