Windowsのバッチプログラミングメモ

Windowsのバッチプログラミングに関する情報を備忘としてメモ書きしています。


※目次をクリックすると目次の下部にコンテンツが表示されます。

  1. システム環境変数
  2. 複数のコマンドを実行
  3. 引数などのバッチパラメータ
  4. 引数内の特殊文字をエスケープ
  5. 引数についている二重引用符を取り除く
  6. 引数から完全パス、親ディレクトリ、ドライブ名を取得
  7. 引数で指定したファイル名の拡張子の処理
  8. 引数で指定したファイル名のタイムスタンプ、ファイルサイズを取得
  9. 環境変数から文字列を抽出、置換
  10. 遅延環境変数
  11. for文で代入した変数から文字列を抽出
  12. リダイレクトの指定
  13. for句、usebackq
システム環境変数
Windowsのバッチファイルでよく使う主なシステム環境変数です。
 
・%CD%
現在いるディレクトリパス
(実行例)
C:\Documents and Settings>echo %CD%
C:\Documents and Settings
 
・%COMPUTERNAME%
コンピュータの名前
 
・%DATE%
現在の日付。date /tと同じ書式
(実行例)
C:\Documents and Settings>echo %DATE%
2013/01/19
 
・%errorlevel%
直前に実行したコマンドのエラーコード。通常、0以外はエラー。
(実行例)
C:\Documents and Settings>diff
‘diff’ は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
C:\Documents and Settings>echo %errorlevel%
9009
 
・%time%
現在の時刻。time /t コマンドと同じ書式
(実行例)
C:\Documents and Settings>echo %time%
5:31:56.95

複数のコマンドを実行

●1行で二つのコマンドを実行
 
コマンド1 & コマンド2
 
実行例)

E:\>dir folder1 & dir folder2
  :
 E:\folder1 のディレクトリ

2013/01/26  07:00    <DIR>          .
2013/01/26  07:00    <DIR>          ..
2013/01/26  06:59                 0 testfile1-1.txt
2013/01/26  06:59                 0 testfile1-2.txt
               2 個のファイル                   0 バイト
               2 個のディレクトリ  20,693,192,704 バイトの空き領域
  :
 E:\folder2 のディレクトリ

2013/01/26  07:00    <DIR>          .
2013/01/26  07:00    <DIR>          ..
2013/01/26  06:59                 0 testfile2-1.txt
2013/01/26  06:59                 0 testfile2-2.txt
               2 個のファイル                   0 バイト
               2 個のディレクトリ  20,693,192,704 バイトの空き領域

 
●1つ目のコマンドが正常終了した場合のみ2つ目を実行
 
コマンド1 && コマンド2
 
実行例)

E:\>dir folder11 && dir folder2
  :
 E:\ のディレクトリ

ファイルが見つかりません

 
●1つ目が失敗した場合のみ2つ目を実行する
 
コマンド1 || コマンド2
 
実行例1)1つ目が成功

E:\>dir folder1 || dir folder2
  :
 E:\folder1 のディレクトリ

2013/01/26  07:00    <DIR>          .
2013/01/26  07:00    <DIR>          ..
n/26  06:59                 0 testfile1-1.txt
n/26  06:59                 0 testfile1-2.txt
               2 個のファイル                   0 バイト
               2 個のディレクトリ  20,693,192,704 バイトの空き領域

 
実行例2)1つ目が失敗

E:\>dir folder11 || dir folder2
  :
 E:\ のディレクトリ

ファイルが見つかりません
  :
 E:\folder2 のディレクトリ

2013/01/26  07:00    <DIR>          .
n/26  07:00    <DIR>          ..
2013/01/26  06:59                 0 testfile2-1.txt
2013/01/26  06:59                 0 testfile2-2.txt
               2 個のファイル                   0 バイト
               2 個のディレクトリ  20,693,192,704 バイトの空き領域

引数などのバッチパラメータ

そのバッチファイル自身のファイル名:%0
バッチファイルの1番目の引数   :%1
バッチファイルの2番目の引数   :%2
  :
バッチファイルの9番目の引数   :%9
 
10個以上ある場合は、shiftコマンドを使用する。
 
例)

test.bat ##################
 @echo off

 echo 本ファイル名は、%0
 echo 1番目の引数は、%1
 echo 2番目の引数は、%2
 echo 3番目の引数は、%3
###########################

実行結果)
E:\batch>test.bat para1 para2 para3
本ファイル名は、test.bat
1番目の引数は、para1
2番目の引数は、para2
3番目の引数は、para3

引数内の特殊文字をエスケープ

コマンドプロンプトからバッチファイルを実行する際、引数内に
アンパサンド(&)、パイプ(|)、かっこ( )
などの特殊文字がある場合、
(^)を対象文字の前につけ、二重引用符で囲む。
 
例)

test.bat ##################
 @echo off

 echo 本ファイル名は、%0
 echo 1番目の引数は、%1
 echo 2番目の引数は、%2
 echo 3番目の引数は、%3
###########################

実行結果)
E:\batch>test.bat "a^&b" "^(a^)" "a^|b"
本ファイル名は、test.bat
1番目の引数は、"a^&b"
2番目の引数は、"^(a^)"
3番目の引数は、"a^|b"

引数についている二重引用符を取り除く

コマンドプロンプトからバッチファイルを実行する際、引数に二重引用符(”)がついている場合、%記号と引数の数字の間に(~)を加えると取り除く事が出来る。
 
例)

test.bat ##################
 @echo off

 echo 本ファイル名は、%0
 echo 1番目の引数は、%~1
 echo 2番目の引数は、%~2
 echo 3番目の引数は、%~3
###########################

実行結果)
E:\batch>test.bat "a^&b" "^(a^)" "a^|b"
本ファイル名は、test.bat
1番目の引数は、a&b
2番目の引数は、(a)
3番目の引数は、a|b

(~)をつけない場合は、下記のように二重引用符がついたまま。

E:\batch>test.bat "a^&b" "^(a^)" "a^|b"
本ファイル名は、test.bat
1番目の引数は、"a^&b"
2番目の引数は、"^(a^)"
3番目の引数は、"a^|b"

引数から完全パス、親ディレクトリ、ドライブ名を取得

●ファイル名を指定した引数を完全パスに展開
 
バッチの引数1に与えられたファイル名を完全パスに展開する場合は、
%~f1
と指定する。
 
例)

test.bat ##################
 @echo off

echo ファイル名は、%1 
echo 完全パスは、%~f1
###########################

実行結果)
E:\batch>test.bat test.txt
ファイル名は、test.txt
完全パスは、E:\batch\test.txt

 
●ファイル名を指定した引数からドライブ名を取得
 
バッチの引数1に与えられたファイル名からドライブ名を取得する場合は、
%~d1
と指定する。
 
例)

test.bat ##################
@echo off

echo ファイル名は、%1 
echo ドライブ名は、%~d1
###########################

実行結果)
E:\batch>test.bat test.txt
ファイル名は、test.txt
ドライブ名は、E:

 
●ファイル名を指定した引数から親ディレクトリパスを取得
 
バッチの引数1に与えられたファイル名から親ディレクトリパスを取得する場合、
%~p1
と指定する。
 
例)

test.bat ##################
@echo off

echo ファイル名は、%1 
echo 親ディレクトリ名は、%~p1
###########################

実行結果)
E:\batch>test.bat test.txt
ファイル名は、test.txt
親ディレクトリ名は、\batch\

引数で指定したファイル名の拡張子の処理

●ファイル名を指定した引数から拡張子を取り除く
 
バッチの引数1に与えられたファイル名から拡張子を取り除いたファイル名を取得する場合、
%~n1
と指定する。
 
例)

test.bat ##################
@echo off

echo ファイル名は、%1 
echo 拡張子なしファイル名は、%~n1
###########################

実行結果)
E:\batch>test.bat test.txt
ファイル名は、test.txt
拡張子なしファイル名は、test

 
●ファイル名を指定した引数から拡張子を取得する
 
バッチの引数1に与えられたファイル名から拡張子を取得するには、
%~x1
と指定する。
 
例)

test.bat ##################
@echo off

echo ファイル名は、%1 
echo ファイルの拡張子は、%~x1
###########################

実行結果)
E:\batch>test.bat test.txt
ファイル名は、test.txt
ファイルの拡張子は、.txt

引数で指定したファイル名のタイムスタンプ、ファイルサイズを取得

●ファイル名を指定した引数からタイムスタンプを取得する
 
バッチの引数1に与えられたファイル名からファイルのタイムスタンプを取得するには、
%~t1
と指定する。

例)

test.bat ##################
@echo off

echo ファイル名は、%1 
echo ファイルのタイムスタンプは、%~t1
###########################

実行結果)
E:\batch>test.bat test.txt
ファイル名は、test.txt
ファイルのタイムスタンプは、2013/01/26 08:08

 
●ファイル名を指定した引数からファイルサイズを取得する
 
バッチの引数1に与えられたファイル名からファイルのファイルサイズを取得するには、
%~z1
と指定する。
 
例)

test.bat ##################
@echo off

echo ファイル名は、%1 
echo ファイルのサイズは、%~z1
###########################

実行結果)
E:\batch>test.bat test.txt
ファイル名は、test.txt
ファイルのサイズは、72

環境変数から文字列を抽出、置換

・%ver:~m%
変数verのm文字目の次の文字から最後まで
 
・%ver:~m,n%
変数verのm文字目の次の文字からn文字分
 
・%ver:~m,-n%
変数verのm文字目の次の文字から最後のn文字分を除去
 
・%ver:~-m%
変数verの語尾から数えてm文字目から最後まで
 
・%ver:~-m,n%
変数verの語尾から数えてm文字目からn文字分
 
・%ver:~-m,-n%
変数verの語尾から数えてm文字目から最後のn文字分を除去
 
・%ver:文字列1=文字列2%
変数ver内の”文字列1″を”文字列2″に置換。
 
(実行例)

test.batの中身 ##################
 @ECHO OFF
  set ver=2013/01/22
  echo ~5    %ver:~5%
  echo ~5,2    %ver:~5,2%
  echo ~5,-3    %ver:~5,-3%
  echo ~-5    %ver:~-5%
  echo ~-5,2    %ver:~-5,2%
  echo ~-5,-3    %ver:~5,-3%
  echo 置換    %ver:2013/=2012/%
#################################
(実行結果)
>test.bat

~5    01/22
~5,2    01
~5,-3    01
~-5    01/22
~-5,2    01
~-5,-3    01
置換    2012/01/22

遅延環境変数

●遅延環境変数を使わずに記述した誤った例

○out2.txtのファイルの中身
100
-100
50
-200

○test1.batのファイルの中身
@ECHO OFF
set file2=C:\batch\out2.txt
set total=0
for /f %%i in (%file2%) do (
   if %%i LSS 0 (
      set /a total=%total% + %%i
   )
)
echo %total%

○実行結果
C:\batch>cmd.exe /k test1.bat
-200

○正しく処理されない理由
 
%total%の変数は、for文が読み取られる時に一度だけ展開され、その際は、初期値の0であり、その後、ループ処理されたときには、変数が展開されないため足し合わされない。
 
実行時に都度、環境変数を展開させるには、遅延環境変数として変数を指定する必要がある。
 
その指定方法は、
setlocal enabledelayedexpansion
を記述して遅延環境変数の展開を有効にし、変数名を”%”ではなく、”!”で囲むようにする。
 
●遅延環境変数を使って記述した正しい例

○out2.txtのファイルの中身
100
-100
50
-200

○test2.batのファイルの中身
@ECHO OFF
setlocal enabledelayedexpansion
set file2=C:\batch\out2.txt
set total=0
for /f %%i in (%file2%) do (
   if %%i LSS 0 (
      set /a total=!total! + %%i
   )
)
echo !total!

○実行結果
C:\batch>cmd.exe /k test2.bat
-300

for文で代入した変数から文字列を抽出

for文で代入した%%iに対して文字列を抽出をする事はできないようで、下記のように一度別の変数に代入後、遅延環境変数(”!”で囲む)を使用して文字列の抽出を行う必要があるようです。
 

○test.batのファイルの中身
@ECHO OFF
setlocal enabledelayedexpansion
set file1=C:\batch\out1.log

for /f %%i in ('findstr err %file1%') do (
   set verDate=%%i
   if "!verDate:~0,10!" == "2013/01/20" (
      echo !verdate!
   )
)

○out1.logのファイルの中身
2013/01/19,err:ファイルがありません。
2013/01/20,inf:ファイルを読み込みます。
2013/01/20,err:ファイルに書き込めません。

○実行結果
C:\batch>test.bat
2013/01/20,err:ファイルに書き込めません。

リダイレクトの指定

●ハンドル
 
入力ストリーム、出力ストリームの場所をハンドルと呼ぶ
 
STDIN 0 標準入力(デフォルト:キーボード)
STDOUT 1 標準出力(デフォルト:コンソール)
STDERR 2 標準エラー出力(デフォルト:コンソール)
UNDEFINED 3-9 
 ハンドルはアプリケーションによって個別に定義される。
 
●リダイレクト演算子
 
>  コンソールの代わりにファイルなどの出力を書き込む
>>  上書きせずに追記で出力を書き込む
<  コマンド入力をファイルから読み取る。   ●ハンドルを複製するには?
 
アンパサンド(&)を使用し、その後にリダイレクトするハンドルの数値を続ける。
 
例)STDERRをSTDOUTに複製する
2>&1
 
例)標準出力、エラー出力ともにコンソールへ出力

C:\batch>dir NotExist
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 0C29-49DF です

 C:\batch のディレクトリ

ファイルが見つかりません

 
例)標準出力をファイル、標準エラー出力をコンソール

C:\batch>dir NotExist > out.log
ファイルが見つかりません

C:\batch>more out.log
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 0C29-49DF です

 C:\batch のディレクトリ

 
例)標準出力、標準エラー出力ともにファイルに出力

C:\batch>dir NotExist > out.log 2>&1

C:\batch>more out.log
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 0C29-49DF です

 C:\batch のディレクトリ

ファイルが見つかりません

for句、usebackq

●サンプルコードの内容
 
・for句でファイルの内容を1行ずつ変数に取り込む。
・取り込むファイル
ファイル名:”out test.log”
(ファイル内の内容)
err:ファイルがありません。
inf:ファイルを読み込みます。
err:ファイルに書き込めません。
 
実行例1)誤用例

test3.bat#######

@ECHO OFF

set file1=C:\batch\out test.log

for /f "tokens=*" %%i in (%file1%) do (
   echo %%i
)
################

実行結果)
C:\batch>cmd.exe /k test3.bat
ファイル C:\batch\out が見つかりません。

→ファイル名にスペースがあるためファイルが見つからない

 
実行例2)誤用例(二重引用符使用)

test3.bat#######

@ECHO OFF

set file1=C:\batch\out test.log

for /f "tokens=*" %%i in ("%file1%") do (
   echo %%i
)
################

実行結果)
C:\batch>cmd.exe /k test3.bat
C:\batch\out test.log

→二重引用符で囲むとファイルではなく、文字列として解釈されてしまう。

 
実行例3)usebackqオプションを使用

test3.bat#######

@ECHO OFF

set file1=C:\batch\out test.log

for /f usebackq %%i in ("%file1%") do (
   echo %%i
)
################

実行結果)
C:\batch>cmd.exe /k test3.bat
err:ファイルがありません。
inf:ファイルを読み込みます。
err:ファイルに書き込めません。

→usebackqオプションを使用して、二重引用符として囲まれた文字列をファイルとして解釈されるようにする。

WebサイトでHTTPリクエスト

関連記事の目次

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です