コマンドプロンプト

バッチ TIPS

実行ファイルパスをカレントディレクトリにする

バッチファイルが置かれているフォルダをカレントディレクトリとする。

@echo off
cd /d %~dp0

空行の echo

echo.

指定時間待つ timeout (wait/sleep)

C:\> timeout 5
5 秒待っています。続行するには何かキーを押してください ...

実行結果を出力しない

> はリダイレクトといい、出力先をコマンドプロンプトでなく指定したファイルに変更します。 nul は空(のファイル)という意味で、書き込んでも何も起きません。 つまり、> nul で出力先を空のファイルに変更することで、コマンドプロンプト上には何も出力されなくなります。
> nul を付けただけだと、エラーメッセージは出力されてしまいます。 さらに 2>&1 を付けることで、エラーメッセージも出力されなくなります。
C:\> mkdir hoge > nul

C:\> mkdir hoge > nul
サブディレクトリまたはファイル hoge は既に存在します。

C:\> rmdir hoge

C:\> mkdir hoge > nul 2>&1

C:\> mkdir hoge > nul 2>&1

引数のダブルクォーテーションを除去する

sample.bat
echo %1
echo %~1
C:\> sample.bat "Hello"
"Hello"
Hello

cmd.exe のエスケープ仕様

解釈のフェーズによってエスケープ仕様が変わる。

if文の中で変数の値が反映されないとき

標準出力の結果を変数に格納する

コマンドプロンプトには該当の機能がないようなので、ちょっとしたテクニックを使って実現します。 次に示す1行のコマンドは time /T の結果を変数 T に格納しています。

FOR /F "DELIMS=" %%A IN ('time /T') DO SET T=%%A

ECHO %T% とすると 15:00 のように時刻が表示されます。

指定したプロセスが起動中かどうか確認する

上記の応用例です。 例としてメモ帳 (notepad.exe) を起動中かどうか判定します。 PID ではなくイメージ名を使っています。

FOR /F "DELIMS=" %%A IN ('tasklist ^| find /C "notepad.exe"') DO SET CNT=%%A

IF %CNT% GTR 0 (
  echo メモ帳を開いています
) else (
  echo メモ帳を開いていません
)

tasklist でプロセスの一覧を取得し、その結果をパイプ | で次の処理に引き渡しています。 このときキャレット ^ を使ってエスケープする必要がある点に注意してください。 find /C "notepad.exe" で notepad.exe という文字列を含む行のみに絞り込み、 その行数をカウントした結果の数値を変数 CNT に格納しています。 IF %CNT% GTR 0 は「もし CNT が 0 より大きかったら」という意味です。

touch

@echo off
if %1. ==. goto end
if not exist %1 (
    type nul > %1
) else (
    copy /b %1 +,, > nul
)

pwd

SET CURRENT_DIR=%cd%

ファイル生成の監視

cd %FOLDER-A%
:loop
if exist *.csv move *.csv %FOLDER-B%
rem 10 秒待つ
ping -n 11 127.0.0.1 >NUL
goto loop