Windowsでファイル名に半角空白が入ったファイル名は本当に扱いにくい。
例えば
for /F %i in ('dir /b') do @echo %i
なんてやったときに、ファイル名に半角空白があるとデリミタと解釈されちゃってtokenが複数入ってしまうなんてことになる。
これを防ぐために半角空白を全てアンダーバーに変えてしまうバッチを作る。動きはこんな感じ。
「コンピューター - ショートカット.lnk」というファイルがあったとして
今回作ったバッチ「blank空白を消すバッチ.bat」をコマンドプロンプトから引数なしで起動実行すると
ファイル名を変更する前後でどうなるかを表示してくれる。
引数なしなので(変更後どうなるかを表示するだけで)実際にファイル名の変更は行わない。
同じバッチファイルを引数Yをつけて実行すると
cmd> blank空白を消すバッチ.bat Y
今度はファイル名の変更を実行する。半角空白がアンダーバーになっているのがわかる。
ソースはこれ。
<注意点>
① 遅延変数
@setlocal enabledelayedexpansion と @endlocal
② for文のデリミタは空白以外にする(今回はスラッシュにした)
for /F "delims=/" %%i in ('dir /b ^| find " "') do (
③ for文の内部での文字列の置き換えはいったん変数に入れる(set)必要あり
set "var=%var:変更前=変更後%"
④ if文で引数1の有無を調べるときはダミー文字列xxをつける
if xx%1==xx (
⑤ REMで始まる行はコメント
自分用のメモだけど、よく使うものばかりなので残してある。
<ソース>
@echo off
@setlocal enabledelayedexpansion
@cls
ECHO. *------------------------------------------------*
ECHO. * 空白削除バッチ *
ECHO. *------------------------------------------------*
ECHO. バッチファイル名:%~n0%~x0
ECHO. %~n0 本体部分名:%~n0
ECHO. %~x0 拡張子名:%~x0
ECHO.
ECHO. 今いるフォルダで「d:\blank空白を消すバッチ.bat」すれば
ECHO. そのフォルダの中について空白削除される
ECHO ~~~~~~~~~~~~~~~~~~~~~~~~
ECHO. ===========================
ECHO. 引数にYを指定したらmove実行
ECHO. ===========================
ECHO.
ECHO %1 変更実行:%1
ECHO ~~~~~~~~~~~~
ECHO 中止する場合は「Ctrl+C」を実行してください
ECHO.
PAUSE
REM ##### 変数定義 #####
SET WK_DATE=%date:~0,4%%date:~5,2%%date:~8,2%
SET WK_TIME=%time:~0,2%%time:~3,2%%time:~6,2%%time:~9,2%
SET WK_DIR=D$\
SET BATCHPATH=%~DP0
REM ~~~~~~~~~~D:\
REM CD /D %BATCHPATH%
SET LOGNM=%BATCHPATH%%WK_DATE%_ログ.txt
REM echo %time% & echo %time:~0,2%%time:~3,2%%time:~6,2%%time:~9,2%
REM 11:32:48.33
REM 11324833
REM ##### 前ログ削除 #####
REM if exist %LOGNM% (
REM echo Y | del %LOGNM%
REM )
REM ##### 処理実行 #####
for /F "delims=/" %%i in ('dir /b ^| find " "') do (
set src=%%i
@echo 変更前:!src!
REM set "line=%line:3=4%" <---- set "var=%var:変更前=変更後%"
REM @echo !src: =_!
set "dst=!src: =_!"
@echo 変更後:!dst!
REM 引数が空かどうかチェック。なければエラーにする。先頭に「xx」を付けて、空にならないようにしている
REM http://www.atmarkit.co.jp/ait/articles/1506/26/news026_2.html
REM これらは特に、片方が空文字列の場合に注意が必要である。例えば引数が1つ以上あるかどうか判定するために「if %1=="" echo error」としても、%1が空文字列だと「if =="" echo error」と解釈され、これは構文エラーとなる。文字列を比較したい場合は、空文字列でも問題ないように、両方に何かのダミー文字列を付けたり、引用符で囲んだりすること。例えば「if "%1"=="" echo error」や「if /%1==/ echo error」のようにする(バッチファイルでは、文字列を引用符で囲む必然性はない)。
if xx%1==xx (
@echo 変更しません
) else (
@move "!src!" !dst!
)
@echo ==========
)
@endlocal
PAUSE
<改良点1>
あとはこれ、このままCドライブ直下で実行してしまうと悲惨な事故になりそう(例えば Program_Files なんてことになりかねない)なので、Cドライブ直下で実行したらエラーで抜ける処理を実装することにする。週末に試す。
<改良点2>
ファイル名に感嘆符(ビックリマーク!)やエスケープ文字(円マーク¥)が含まれているときの動作もテスト必要。