LoginSignup
55
81

More than 5 years have passed since last update.

すごいDOSバッチ (コピペで)たのしく逃げよう!

Last updated at Posted at 2017-05-14

「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
55
81
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
55
81