プロジェクト

全般

プロフィール

Windowsバッチファイル

Windows OSが標準搭載する、コマンドを組み合わせてスクリプト実行する環境は、MS-DOS時代からのバッチファイル、WSH、PowerShellの3つです。
CUI(コマンドプロンプト)環境で使うならバッチファイルになると思います。

逆引きバッチ処理

バッチの起動・終了

バッチ起動時にコマンドプロンプトを最小化させる

ショートカットからバッチファイルを起動するときは、ショートカットのプロパティで実行時の大きさ欄を[最小化]に設定しておくとバッチファイル起動時に開くコマンドプロンプトがタスクバーに格納された状態となります。
ショートカットなしにバッチファイルを起動したときに、コマンドプロンプトをタスクバーに格納された状態にするには、次のようにバッチファイルの先頭に記述します。

@echo off
if not "%~0"=="%~dp0.\%~nx0" (
  start /min cmd /c,"%~dp0.\%~nx0" %*
  goto :eof
)

バッチファイルの処理を終了させる

exit /b 1

戻り値を1としてバッチファイルを終了させます。
GOTO :EOF

暗黙のラベルEOFはバッチファイルの最後を意味します。GOTO文で指定するとき、コロンは他のラベルとは違い必須です。

コメントを書きたい

  1. 行の先頭にrem
    rem コメントだよ
  2. 行の先頭に::
    :: コメントだよ(実はラベル)

    ラベル(GOTO文の飛び先等)は行頭にコロン1つですが、コメントであることを規約的に明示するために2つコロンを並べています。

バッチのコマンドライン引数

バッチファイルのコマンドに引数を指定し、それを取得して処理を変える等に利用することができます。
バッチファイルを実行するコマンドラインに指定した引数は最大9個まで、次の変数に格納されています。

%1 %2 %3 %4 %5 %6 %7 %8 %9

10個以上コマンドラインに引数を指定した場合は、%1を処理したあとに@shiftを実行することで、%2が%1へ、%3が%2へと順に一つずつずらされます。
必要に応じて引数を取り出しながら@shiftを実行していきます。

また、%* とするとコマンドライン引数全体を取ることができます。(まとめて一つの文字列として取れる?)

バッチのコマンドラインの引数は、空白文字だけでなく、=;,も引数の区切りとして扱われます。

ファイル・ディレクトリ操作

バッチファイルの存在するディレクトリをカレントディレクトリにしたい

cd /d %~dp0
  • %0 が実行されたバッチファイルのフルパス(ダブルクォートで囲われた文字列)
  • ~ がダブルクォートを除去
  • d はドライブ文字だけ取り出し
  • p はパス(ドライブ文字およびファイル名を除いた文字列)

ファイルが実在するか調べたい

if exist "C:\Program Files\Foo" goto FOO_EXISTS
   | 中略
:FOO_EXISTS
   echo "あったよ" 
  • if not exist も使えます。

goto文を使わない

if exist "C:\Program Files\Foo" (
    echo "あったよ" 
) else (
    echo "なかったよ" 
)

ファイルの数を数えたい

set num=0
for %%f in (data\*.dat) do (
    set /a num+=1
)
echo ファイル数は、%num%

for文で、処理対象ファイルをワイルドカードで複数指定しています。(data\*.dat)
該当するファイル名が入る変数はアルファベット1文字の制約があります。%%f
数を数えるカウンタとする変数は、数値として計算するのでset /aと右辺を数値で扱うようにしています。

環境変数

バッチファイル内でのみ有効な変数を使いたい

setlocal
set FOO=abc
  :
endlocal
echo %FOO%  <--- 未定義エラー

変数をクリアしたい

T.B.D.

変数の文字列を置換したい

set BAR=%FOO:ab=AB%

変数の文字列の部分文字列を取り出したい

次の書式で、変数の文字列の部分文字列が取り出せます。

%変数名:~開始位置,文字数%

TEXT=AlfaBravo

指定例 結果例 備考
TEXT:~0,4 Alfa 文字の位置は先頭が0
TEXT:~,4 Alfa 開始位置を省略すると先頭(0)から
TEXT:~4,5 Bravo
TEXT:~3,4 aBra

コマンド実行結果を変数に代入したい

C:\> for /f %i in ('dir /A-D /B /S %APPDATA%\NetBeans ^| findstr checkstyle.jar') do set CHECKSTYLE_JAR=%i
  • バッチファイル中に記述するときは、%i を%%iと記述します。
  • コマンドライン中に、パイプ記号、リダイレクト記号、ダブルクォート、シングルクォートを使うときは、^でエスケープします。

数式の計算結果を変数に代入したい

set x=3
set /a y=%x%*2

/aオプションを付けると、右辺を数式として計算した結果を左辺の変数に代入します。
/aオプションがないと、右辺は文字列として左辺に代入されます(この例では、3*2が変数y)。

文字列処理

文字列を比較したい

if "%1"=="alfa" goto ALFA

ファイル内の文字列を置換したい

setlocal enabledelayedexpansion
for /f "delims=" %%I in (input.txt) do (
    set line=%%I
    echo !line:abc=ABC!>> output.txt
)
endlocal
  • 遅延環境変数の展開を有効化します
    でないと、forの処理で最後の行だけが有効になってしまうためです。
    遅延環境変数はコマンド実行時に展開されますが、通常の環境変数は解析時に展開されます。
    遅延環境変数は、%foo%ではなく!foo!で示します。

変数の文字列置換を使用しています。%変数名:置換元=置換後% で変数の文字列の中に含まれる置換元文字列が置換後文字列に置換された文字列が得られます。

ファイルの先頭一行を除きたい

set outfile=result.csv
for /f "tokens=* skip=1" %%l in (original.csv) do (
    echo %%l>>%outfile%
)
  • for /f で対象ファイルの内容を行単位でループ処理します。
  • tokensで各行の文字列を一括で変数に取り込みます(ここでは変数lに)。
    tokens=1,3 とすると、各行のデリミタで区切られた文字列の1番目と3番目を変数に取り込みます(変数は2個指定する)。
  • skip=1で先頭1行が対象外となります。
  • 行全体を変数outfileのファイルに追記します。
複数のCSVファイルを1つのCSVファイルに結合する

複数のCVSファイルを1つのファイルに結合します。ただし、各ファイルの先頭行には項目名の行があり、結合後はファイル先頭にのみ項目名の行を残すものとします。

文字列をコンソールへ表示させたい

echo こんにちは、バッチファイルです。
  • 次の記号を文字として表示させるには、^を使ってエスケープが必要です。
    < > | & ^


    echo 書式: copy ^<コピー元^> ^<コピー先^>

エラー処理

コマンド実行結果が成功か失敗かを判別したい

copy xxx yyy
if ERRORLEVEL 1 goto FAIL

クリップボードから画像を追加 (サイズの上限: 1 GB)