Page Top
Windows

Batchとは

昔からある、コマンドプロンプトの書式をテキスト化したもの。
window10になって、powerShell がメイン?になったらしいが、まだ batch も現役。

環境変数

set

とだけ打つと、現在の環境変数の一覧が返される。

set maya

と打つと、mayaと名前が付く変数だけにフィルタされ、リストが返る。
全文字打たなくてもいいので、これ知っておくと便利。

set name=unitbus

= で値を指定することで、コマンドプロンプト内や、
bat内で、一時的に使用したり、変更出来たりする。
すでに使われてないかを気を付ける必要がある。

set PATH=%PATH%;C:/test

追加したい場合は、自身を加えて、セミコロンで追記する。

システムに影響与えるには setx を使う。

シンボリックリンクと、ジャンクション

シンボリックリンクは管理者権限無いと作成出来ない。
ジャンクションにすれば気軽に作れる。作成するコマンドは一緒。

mklink /J C:\Users\%USERNAME%\AppData\Roaming\Mozilla U:\data\Mozilla

改行して、複数行で書く

batで、1つのコマンドに複数行にしたい場合は、行末に ^ を入れるとできる。

echo

メッセージを表示したい時に使う。

@echo 日本語

@ を使うと、入力したコマンドの表示を隠す事が出来る。
メッセージ自体は表示されるので、二重に表示されるような見た目にならない。

メッセージだけを、相手に読ませたい時は、batの一行目で、echo 自体を無効にしておけば良い。

@echo off
echo 日本語

改行だけを表示したい時は、 echo. を使う。
echo だけだと、エコー設定の状態が表示されので注意。

@echo off の状態で、外部ファイルを実行した時に、
コマンドの内容をログとして残したい場合は以下のように書ける。

@echo off
echo エクスプローラーを起動
echo.
echo ^
explorer.exe "%TMP%"
explorer.exe "%TMP%"
pause

メッセージボックス

一時的にvbsファイルを生成する必要があるが、一行で出す事は可能。

echo msgbox "メッセージ",vbCritical,"タイトル" > %TEMP%/msgbox_tmp.vbs & %TEMP%/msgbox_tmp.vbs

文字の置き換え

set moji=検索文字
set moji=%moji:検索=置換%
echo %moji%

文字列のスライス

文字列の一部を削除したい時は、スライスを使います。

@echo off
set value=test.ext
echo %value:~-4%

pauseの無効化

別のバッチファイル内のpauseを無効化したい場合は、パイプを使って、
右のバッチの結果を、エコーするって感じで回避できる。

echo | "F:\tmp\convertA.bat"
echo | "F:\tmp\convertB.bat"

参考

Qiita: コマンドプロンプトの自分用メモ
https://qiita.com/yuji38kwmt/items/6866fbcb3175ef1c897a

入力待機とスキップ

set /p ANS="実行する(Y/N)?"
if /i {%ANS%}=={n} goto :EOF

/pオプションを使うと、ユーザーの入力した文字を変数に入れる事ができる。
変数をもとに、処理を部分的に回避したり、終了したり出来る。

/iは大文字小文字の区別をなくす。

test.bat < nul

毎回きかれて面倒なら、コマンドプロンプトから上の書き方でバッチファイルを呼び出せば、
全工程の入力処理をスキップしてくれるので、環境変数のANSは常にカラになり、無視されるようになる。
なので、事前に処理はすべてYesを推奨するように書いておくと良い。

コマンドプロンプトが嫌なら、これ自体をバッチにして「送る」に登録しておくと便利。

<が標準入力(stdin)の事で、通常テキストファイルを指定する。
nulは特殊文字で、コマンド内ではNULLの役目を果たす。

日付

%date% に、2019/09/22 みたいな形で、日付は格納されてる。
/ を取りたい時は、スライスを利用( 20190922 )。

set date_now=%date:~-10,4%%date:~-5,2%%date:~-2,2%
echo %date_now%

時間

%time% に、 1:06:55.71 みたいな形で、時間は格納されてる。
スペースあったりクセが強いので、ファイル名とかに使う時は、010655 みたいに変換が必要。

set time_now=%time:~0,2%%time:~3,2%%time:~6,2%
echo %time_now: =0%

クリップボードの文字の置換

パスをコピーして、スラッシュだとエクスプローラーで開けず、イライラする時に実行。
コピーしたパスを、バックスラッシュに置き換えて、クリップボードに戻してくれます。
powershell使ってますが、batで保存。 送るに入れると便利。
送るに入れても仕方ないですね…。デスクトップとかに置くとかですかね。

powershell "$s = get-clipboard; $s.Replace('/', '\').toString().trimend([environment]::newline) + [convert]::tochar(0) | clip"

フォルダの判別

%~a1で、1個目の引数からアトリビュート(属性)を取得できる。
フォルダの場合、先頭にdが付くので、それを元に振り分ける感じ。

echo %~ftza1
set ATTR=%~a1
if %ATTR:~0,1%==d goto :TO_FOLDER

echo ファイル: %~n1
goto :EOF

:TO_FOLDER
echo フォルダ: %~nx1

テキストでループ

テキストファイルからリストを取得してループしたい場合に利用。
環境変数や引数だと文字数の限界があるので、大量のファイルを扱う場合の必須テク。

for /f "usebackq delims=" %%t in (%1) do call :EXEC "%%t"
echo LOOP FIN.
exit /B %errorlevel%

:EXEC
echo %~1

forを使い、/fでファイルモードにする。
扱うテキストにスペースが含まれる場合、デフォルトだと区切り文字と判断されてしまうので、
区切り文字を改行だけにしたい場合は、delimsを空にする必要がある。
更に、開く予定のテキストファイル自体にスペースが含まれてる場合は、usebackqで回避出来る。

複数行の処理になる場合は直接書かず、callで飛ばす。
callは引数を持たせたり、処理を戻す事が出来る。
callは、同じファイル内のラベルに飛ばしたり、肥大化してきたら別ファイルにして呼び出すことも可能。
callで飛ばした引数は、受けて側で%1みたいに使える。
%0にはラベル名、外部ファイルならファイルパスが入る。

batでファイル名を扱うときは、基本的に"で囲んで渡し、受け取る時に%~1で取る。暗黙のルール的な感じ。
D&Dの場合、"の有無はwindows側が勝手に判断して付けるので、付いてる前提にしておく。
アプリケーションにわたす時も、app.exe "%~1"みたいに、ひと手間入れる癖付けると良い。
スペースや記号を使わせなければ良い話だが、トラブル対応する側は覚えておく必要がある。

引数が要らない場合はgotoでも可。gotoは戻ってこない。
途中で終わらせたい場合は、goto :EOF使うなど、ちょっと書き方がかわる。