「DOSバッチファイル」、嫌な響きですね...。
DOSバッチの作成依頼は、心の準備をしていないときに突然降って湧くもので、毎回毎回、for
文の書き方をググってはハマり、環境変数の即時展開でハマり、「(の使い方が誤っています
」「0の使い方が誤っています
」等の言葉足らずのエラーに苦しめられる。こんな思い、二度としたくない。
でもいまさらDOSバッチの勉強なんてしたくない。
そんな時に備えて、DOSバッチでよく使うコードスニペットを用意しておきました。華麗にコピペで逃げましょう。
文字列操作等は関数化しています(結果の文字列は関数と同名の変数に格納されます)。勢いに乗って、Python的な文字列スライス関数(Slice
)も作成しました。
バージョン情報
C:\>ver
Microsoft Windows [Version 6.1.7601]
コピペで逃げよう
@echo off
setlocal
rem ============================================================
rem
rem main
rem
rem ============================================================
rem このバッチファイルのカレントディレクトリへ移動
cd /d "%~dp0"
rem -------------------------------------------------------------
rem 前処理
rem -------------------------------------------------------------
rem バッチファイル名(拡張子つき)の取得
set prog_name="%~nx0"
echo %prog_name%を起動しました。
rem バッチファイル自身のフルパス(例:「C:\bat\sample.bat」)
set target_file="%~f0"
rem バッチファイルの格納先ディレクトリ(例:「C:\bat\」)
set target_dir="%~dp0"
rem ファイルの存在チェック
call :FileExist "%target_file%"
if %ERRORLEVEL% equ 1 (
echo ファイル(%target_file%)が見つかりました。
) else (
echo ファイル(%target_file%)が見つかりません。
exit /b 1
)
rem ディレクトリの存在チェック
call :DirExist "%target_dir%"
if %ERRORLEVEL% equ 1 (
echo ディレクトリ(%target_dir%)が見つかりました。
) else (
echo ディレクトリ(%target_dir%)が見つかりません。
exit /b 1
)
rem -------------------------------------------------------------
rem みんなに愛されてないFor文
rem -------------------------------------------------------------
rem 単語のイテレーション
for %%a in (aaa bbb ccc) do (
set x=%%a
call echo %%x%%
)
rem 整数のイテレーション
for /l %%a in (1,1,10) do (
set x=%%a
call echo %%x%%
)
rem ファイルのイテレーション
for %%a in (*.bat) do (
set x=%%a
call echo %%x%%
)
rem ファイルのイテレーション(サブディレクトリも再帰的に検索)
for /r %%a in (*.bat) do (
set x=%%a
call echo %%x%%
)
rem ディレクトリのイテレーション
for /d %%a in (*) do (
set x=%%a
call echo %%x%%
)
rem ディレクトリのイテレーション(サブディレクトリも再帰的に検索)
for /d /r %%a in (*) do (
set x=%%a
call echo %%x%%
)
rem CSVファイルの行イテレーション(各行のフィールド値をa,b,cに割り当て)
for /f "tokens=1-3 delims=," %%a in (sample.csv) do (
echo [%%a %%b %%c]
)
rem コマンド実行結果の取得(例:CSVファイルの行数の取得)
set CMDSTR="type sample.csv | find /c /v """
for /f "usebackq delims=" %%a in (`%CMDSTR%`) do (
set lines=%%a
)
echo %lines%
rem ファイル情報の取得
call :GetFileInfo .\sample.bat
echo %GetFileInfo.FileName%
echo %GetFileInfo.DirName%
echo %GetFileInfo.UpdateDate%
rem 数字列かの判定
call :IsNumeric 2147483647
echo IsNumeric 2147483647 =^> %ERRORLEVEL%
call :IsNumeric 214x483647
echo IsNumeric 214x483647 =^> %ERRORLEVEL%
call :IsNumeric -214x483647
echo IsNumeric -214x483647 =^> %ERRORLEVEL%
rem -------------------------------------------------------------
rem 文字列操作
rem -------------------------------------------------------------
echo ==== 文字列操作 ==================
rem 部分文字列の切り出し
call :SubStr abcdef 2 3
echo SubStr abcdef 2 3 =^> %SubStr%
rem 部分文字列の置換
call :Replace abcdef cde CDE
echo Replace abcdef cde CDE =^> %Replace%
rem 文字列の反転
call :Reverse ABCDEF
echo Reverse ABCDEF =^> %Reverse%
rem 小文字→大文字変換
call :UpCase abcdefg
echo UpCase abcdefg =^> %UpCase%
rem 大文字→小文字変換
call :DownCase ABCDEFG
echo DownCase ABCDEFG =^> %DownCase%
rem 文字列のスライス(インタフェース仕様はPythonと同じ)
call :Slice 123456789 "" "" -1
echo Slice 123456789 "" "" -1 =^> %Slice%
rem -------------------------------------------------------------
rem 年月日の取得
rem -------------------------------------------------------------
call :GetYear & call :GetMonth & call :GetDay & call :GetHour & call :GetMin & call :GetSec
echo GetYear ^(%DATE% %TIME%^) -^> [%GetYear%,%GetMonth%,%GetDay%,%GetHour%,%GetMin%,%GetSec%]
endlocal
exit /b 0
rem ============================================================
rem
rem プロシージャ群
rem
rem ============================================================
rem ============================================================
rem FileExist - ファイルの存在チェック(UNCパス/NFSパスにも対応)
rem ============================================================
:FileExist
if exist "%1" (
if not exist "%1\*" (
exit /b 1
)
)
exit /b 0
rem ============================================================
rem DirExist - フォルダの存在チェック(UNCパス/NFSパスにも対応)
rem ============================================================
:DirExist
if exist "%1\*" (
exit /b 1
)
exit /b 0
rem ============================================================
rem GetFileInfo - ファイルの情報
rem ============================================================
:GetFileInfo
set GetFileInfo.FilePath=%1
for %%a in (%GetFileInfo.FilePath%) do (
set GetFileInfo.FileName=%%~nxa
set GetFileInfo.FileNameNoExt=%%~na
set GetFileInfo.ExtName=%%~xa
set GetFileInfo.DirName=%%~dpa
set GetFileInfo.UpdateDate=%%~ta
set GetFileInfo.FileSize=%%~za
)
exit /b 0
rem ==============================================
rem StrLen - 文字数のカウント
rem ==============================================
:StrLen
set _target=%1
set _cou=0
if not defined _target (
set StrLen=0
exit /b 0
)
:__STRLEN_START__
call set _target=%%_target:~1%%
set /a _cou+=1
if defined _target (
goto __STRLEN_START__
)
set StrLen=%_cou%
exit /b 0
rem ============================================================
rem SubStr - 文字列の切り出し(0オリジン)
rem ============================================================
:SubStr
set SubStr._target=%1
set SubStr._start=%2
set SubStr._length=%3
call set SubStr=%%SubStr._target:~%SubStr._start%,%SubStr._length%%%
exit /b 0
rem ============================================================
rem Replace - 文字列置換(0オリジン)
rem ============================================================
:Replace
set Replace._target=%1
set Replace._old=%2
set Replace._new=%3
call set Replace=%%Replace._target:%Replace._old%=%Replace._new%%%
exit /b 0
rem ============================================================
rem Slice - 文字列スライス(インタフェース仕様はPythonと同じ)
rem ============================================================
:Slice
set Slice._target=%1
set Slice._start=%~2
set Slice._end=%~3
set Slice._step=%~4
if not defined Slice._target (
exit /b 0
)
call :StrLen %Slice._target%
set /a Slice._target_len=%StrLen%
rem ---------------------------------------
rem デフォルト値の設定
rem ---------------------------------------
rem ステップ
if not defined Slice._step (
set /a Slice._step = 1
)
rem スタート・エンド
if %Slice._step% geq 0 (
if not defined Slice._start (
set /a Slice._start = 0
)
if not defined Slice._end (
set /a Slice._end = Slice._target_len
)
) else (
if not defined Slice._start (
set /a Slice._start = Slice._target_len - 1
)
if not defined Slice._end (
set /a Slice._end = Slice._target_len * -1 - 1
)
)
rem ---------------------------------------
rem スタート・エンドが負の数→正の数に変換
rem ---------------------------------------
if %Slice._start% lss 0 (
set /a Slice._start += Slice._target_len
)
if %Slice._end% lss 0 (
set /a Slice._end += Slice._target_len
)
rem ---------------------------------------
rem エンドの調整
rem ---------------------------------------
if %Slice._step% geq 0 (
set /a Slice._end -= 1
) else (
set /a Slice._end += 1
)
set Slice._target_sliced=
for /l %%a in (%Slice._start%,%Slice._step%,%Slice._end%) do (
call set Slice._target_char=%%Slice._target:~%%a,1%%
call set Slice._target_sliced=%%Slice._target_sliced%%%%Slice._target_char%%
)
set Slice=%Slice._target_sliced%
exit /b 0
rem ============================================================
rem Reverse - 文字列反転
rem ============================================================
:Reverse
set Reverse._target=%1
if not defined Reverse._target (
exit /b 0
)
call :StrLen %Reverse._target% & set /a Reverse._target_len=%StrLen%-1
set Reverse._target_rev=
for /l %%a in (%Reverse._target_len%,-1,0) do (
call set Reverse._target_char=%%Reverse._target:~%%a,1%%
call set Reverse._target_rev=%%Reverse._target_rev%%%%Reverse._target_char%%
)
set Reverse=%Reverse._target_rev%
exit /b 0
rem ============================================================
rem DownCase - 大文字→小文字変換
rem ============================================================
:DownCase
set DownCase._target=%1
for %%a in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do (
call set DownCase._target=%%DownCase._target:%%a=%%a%%
)
set DownCase=%DownCase._target%
exit /b 0
rem ============================================================
rem UpCase - 小文字→大文字変換
rem ============================================================
:UpCase
set UpCase._target=%1
for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
call set UpCase._target=%%UpCase._target:%%a=%%a%%
)
set UpCase=%UpCase._target%
exit /b 0
rem ============================================================
rem IsNumeric - 数字のみかの判定
rem ============================================================
:IsNumeric
set IsNumeric._target=%~1
if %IsNumeric._target:~0,1%==- (
call set IsNumeric._target=%%IsNumeric._target:~1%%
)
for /l %%i in (0,1,9) do (
call set IsNumeric._target=%%IsNumeric._target:%%i=%%
if not defined IsNumeric._target (
exit /b 1
)
)
if not defined IsNumeric._target (
exit /b 1
)
exit /b 0
rem ============================================================
rem GetYear - 年の取得
rem ============================================================
:GetYear
set GetYear=%DATE:~0,4%
exit /b 0
rem ============================================================
rem GetMonth - 月の取得
rem ============================================================
:GetMonth
set GetMonth=%DATE:~5,2%
exit /b 0
rem ============================================================
rem GetDay - 日の取得
rem ============================================================
:GetDay
set GetDay=%DATE:~8,2%
exit /b 0
rem ============================================================
rem GetHour - 時の取得
rem ============================================================
:GetHour
set GetHour=%TIME:~0,2%
set GetHour=%GetHour: =0%
exit /b 0
rem ============================================================
rem GetMin - 分の取得
rem ============================================================
:GetMin
set GetMin=%TIME:~3,2%
rem ============================================================
rem GetSec - 秒の取得
rem ============================================================
:GetSec
set GetSec=%TIME:~9,2%
exit /b 0