コマンドプロンプト（cmd.exe）私的メモ

2019/02/23 変更
* 「前月の日付を得る」を追加
* シンタックスハイライト `bat` がきかなくなったので削除
* タグのバージョンを最新化

---
##スクリプト（.cmd）のあるフォルダを取得する
`%~dp0` を使う。

###スクリプト例

```ex_script　folder.cmd
@echo off
echo %%0    = %0
echo %%~0   = %~0
echo %%~d0  = %~d0
echo %%~p0  = %~p0
echo %%~dp0 = %~dp0
```

###実行例
スクリプトがフォルダC:\localにある場合
（`%~0` を試すだけのためにファイル名にスペースを入れている）

```
> "ex_script　folder"
%0    = "ex_script　folder"
%~0   = ex_script　folder
%~d0  = C:
%~p0  = \local\
%~dp0 = C:\local\
```

##パラメータ（%1, %2, ...）が指定されたのチェック
`if "%~1" == ""` を使う。

###スクリプト例

```ex_parameter_null_check.cmd
@echo off
if "%~1" == "" goto usage
echo %~1
goto end
:usage
echo Usage: %~n0 ^<string^>
goto end
:end
```

###実行例

```
> ex_parameter_null_check
Usage: ex_parameter_null_check <string>
```

```
> ex_parameter_null_check ""
Usage: ex_parameter_null_check <string>
```

```
> ex_parameter_null_check "Hello, World!"
Hello, World!
```

##ローカル変数を使う
`setlocal` と `endlocal` を使う。

###スクリプト例

```ex_setlocal.cmd
@echo off
setlocal
echo (1) TEST_ENV = %TEST_ENV%
set TEST_ENV=Local value.
echo (2) TEST_ENV = %TEST_ENV%
endlocal
echo (3) TEST_ENV = %TEST_ENV%
```

###実行例

```
> set TEST_ENV=Global value.
> ex_setlocal
(1) TEST_ENV = Global value.
(2) TEST_ENV = Local value.
(3) TEST_ENV = Global value.
```

##作業用のフォルダに一時的に移動してまた戻る
`pushd` と `popd` を使う。

###スクリプト例
（ここではスクリプトのあるフォルダに移動している）

```ex_pushd.cmd
@echo off
echo (1) CD = %CD%
pushd %~dp0
echo (2) CD = %CD%
popd
echo (3) CD = %CD%
```

###実行例

```
> c:\local\ex_pushd
(1) CD = c:\
(2) CD = c:\local
(3) CD = c:\
```

##大文字、小文字に変換する
`%変数:置換元文字列=置換先文字列%` を使う。
置換元文字列の大文字・小文字は区別されないので、以下の動作となる。
%ENV:A=A% ・・・ a または A → A
%ENV:a=a% ・・・ a または A → a

###スクリプト例

```to_upper.cmd
@echo off
setlocal
if "%~1"=="" goto :end
set upper=%~1
for %%i 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 upper=%%upper:%%i=%%i%%
echo %upper%
:end
endlocal
```

```to_lower.cmd
@echo off
setlocal
if "%~1"=="" goto :end
set lower=%~1
for %%i 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 lower=%%lower:%%i=%%i%%
echo %lower%
:end
endlocal
```

###実行例

```
> to_upper "Hello, World!"
HELLO, WORLD!

> to_lower "Hello, World!"
hello, world!
```

##コマンド置換を行う
``for /f "usebackq delims=" in (`<command>`)`` を使う。

###スクリプト例

```bat:ex_command_substitution.cmd
@echo off
setlocal
for /f "usebackq delims=" %%t in (`ver`) do set RESULT=%%t
echo Result: %RESULT%
endlocal
```

###実行例

```
> ex_command_substitution
Result: Microsoft Windows [Version 6.1.7601]
```

ちなみに delims= がないと以下の結果となる。

```
Result: Microsoft
```

##前月の日付を得る
以下を組み合わせて使う。
* `%変数:/=%` （'/' を削除）
* `set /a 変数=式` （計算）※数字が0で始まると8進数hなので注意
* `%変数:~n,m%` （部分文字列）※`n`は0始まり

###スクリプト例
```last_month.cmd
@echo off
setlocal

if "%~1"=="" (
  set today=%DATE%
) else (
  set today=%~1
)

echo 今日は %today% です。

rem 2019/01/15 => 20190115
set yyyymmdd=%today:/=%

rem 20190115 => 201901
set yyyymm=%yyyymmdd:~0,6%

rem 20190115 => 01
set mm=%yyyymmdd:~4,2%

rem 201901 => 201812
if "%mm%"=="01" (
  set /a yyyymm=%yyyymm%-89
) else (
  set /a yyyymm=%yyyymm%-1
)

rem 201812 => 2018/12
set last_month=%yyyymm:~0,4%/%yyyymm:~4,2%

echo 先月は %last_month% です。
```

###実行例
```
> last_month
今日は 2019/02/23 です。
先月は 2019/01 です。

> last_month 2019/01/15
今日は 2019/01/15 です。
先月は 2018/12 です。
```