Windows バッチ処理 まとめ

## 目次
1. [ワイルドカード](#1-ワイルドカード)
1. [リダイレクト](#2-リダイレクト)
1. [パイプ](#3-パイプ)
1. [環境変数](#4-環境変数)
1. [文字列操作](#5-文字列操作)
1. [引数](#6-引数)
1. [if文](#7-if文)
1. [for文](#8-for文)
1. [バッチコマンド](#9-バッチコマンド)


## 1. ワイルドカード
* <strong>*</strong> : 任意の長さの文字列(0文字から)
* <strong>?</strong> : 任意の1文字(0文字も可)

```powershell
# 例
# txtファイルを削除
$ del *.txt

# page~.jpgを削除
$ del page?.jpg
```

## 2. リダイレクト
標準出力の出力先を画面からファイルなど任意のデバイスへ変更する。

```powershell
# 標準出力の出力先を画面からファイルに変更する
$ コマンド > ファイル名
$ dir > file.txt

# 追加書き込みをする
$ コマンド >> ファイル名
$ echo Hello >> file.txt

# エラー内容を書き込む
$ コマンド 2> ファイル名
$ dir *.txt 2> file.txt

# 標準出力、標準エラー入力どちらも書き込む
$ コマンド > ファイル名 2>&1
$ dir *.txt > file.txt 2>&1

# 標準入力の入力元をファイルに変更する
$ コマンド < ファイル名
$ sort < file.txt

# 組み合わせも可能
# file1.txtの入力内容をsortで読み、標準出力結果をfile2.txtに書き込む
$ sort < file1.txt > file2.txt
```

## 3. パイプ
コマンドの実行結果をさらに別のコマンドを使って処理する。

```powershell
# コマンドを連結する
$ コマンド1 | コマンド2 | コマンド3 | ...
$ dir /b | sort
```

### 単純にコマンドを続けて実行したい場合

```powershell
# 書式は以下の通り
$ コマンド1 & コマンド2 & コマンド3 & ...

# 実質1行ずつ実行した場合と変わらない
$ コマンド1
$ コマンド2
$ コマンド3
...

# コマンドの実行が成功したら次のコマンドを実行させたい場合
$ コマンド1 && コマンド2 && コマンド3 && ...
```

## 4. 環境変数
環境変数の値を表示、参照、設定、削除する。

```powershell
# 環境変数の値を表示する
$ set        # 全部表示
$ set test   # testを表示

# 環境変数の値を参照する
$ %環境変数名%
$ echo %test%

# 環境変数の値を設定する
$ set 変数名=値
$ set test=テスト;

# 環境変数の値を削除する
$ set 変数名=
$ set test=

# 「|」「<」「>」「&」「^」などの特殊文字は、文字の前に「^」をつける
$ set test=^|ABC

# 環境変数に式の結果を使用する
$ set /a 式
$ set /a num=1+1

# ユーザーからの入力を値として設定する
$ set /p 変数名=[プロンプト文字列]
$ set /p num=数字を入力してください
```

## 5. 文字列操作
文字列の切り抜き、置換など。

|書式|意味|
|---|----|
|%V%|変数Vの値全体|
|%V:~m%|m文字目から、最後まで|
|%V:~m,n%|m文字目から、n文字分|
|%V:~m,-n%|m文字目から、最後のn文字分を除いたもの|
|%V:~-m%|後ろからm文字目から、最後まで|
|%V:~-m,n%|後ろからm文字目から、n文字分|
|%V:~-m,-n%|後ろからm文字目から、最後のn文字分を除いたもの|
|%V:c1=c2%|文字c1を文字c2に置換する。それぞれ複数の文字を指定することも可能|

## 6. 引数
引数の値を設定、参照する。

```powershell
# バッチを呼び出すときに、引数を設定する
$ バッチ名 引数1 引数2 ...
$ test.bat "ABC" "DEF" ...

# 設定した引数を参照する
$ echo 第一引数は「%1」です
$ echo 第二引数は「%2」です

# 引数を参照する時の書き方について
# %~1	ダブルクォーテーション「”」を除く
# %~f1	フルパスすべてを表示
# %~d1	ドライブ名を抜き出す
# %~p1	パスのみを抜き出す
# %~n1	ファイル名を抜き出す
# %~x1	拡張子を抜き出す
# %~s1	短い名前にする
# %~a1	ファイルの属性を抜き出す
# %~t1	ファイルの日付・時刻を抜き出す
# %~z1	ファイルのサイズを抜き出す
```

## 7. if文
if文で条件分岐を行う。

```powershell
# if文で条件分岐を行う
# 条件に合致すればコマンド1, ダメならばコマンド2を実行する
$ if 条件式 コマンド1 else コマンド2

# else以下は省略することも可能
$ if 条件式 コマンド1

# 条件式を複数設定する
# どちらも真であればコマンドを実行する
$ if 条件式1 if 条件式2 コマンド1

# 複数行で分けたい場合は、カッコ()を使う
$ if 条件式 (
$   コマンド1
$   コマンド2
$ ) else (
$   コマンド3
$   コマンド4
$ )
```

### 比較演算子の種類
|演算子|意味|
|-----|----|
|==|等しいとき|
|not ==|等しくないとき|
|defined|変数が定義されているとき|
|not defined|変数が定義されていないとき|
|exist|ファイル、ディレクトリが存在するとき|
|not exist|ファイル、ディレクトリが存在しないとき|
|equ|等しいとき|
|neq|等しくないとき|
|lss|プログラミング言語で言う「<」|
|leq|プログラミング言語で言う「<=」|
|gtr|プログラミング言語で言う「>」|
|geq|プログラミング言語で言う「>=」|

**※なお比較演算子は、「/i」オプションをつけることで、大文字と小文字の区別をせずに比較できる**

## 8. for文
繰り返し処理を実行する。

```powershell
# for文
$ for [オプション] %%変数 in [セット] do (
$   コマンド1
$   コマンド2
$ )

# 数値を開始から終了まで変化させて実行する
# /lオプションをつける
$ for /l %%変数 in (開始,ステップ,終了) do コマンド
$ for /l %%n in (1,1,10) do (
$   echo n = %%n
$ )

# 指定した複数の要素を順に変数に格納しながら繰り返しを行う
$ for %%変数 in (セット) do コマンド
$ for %%f in (note.txt memo.txt report.doc) do (
$   echo filename = %%f
$ )

# ワイルドカードを使って繰り返しを行う
$ for %%f in (*.txt) do (
$   echo filename = %%f
$ )

# フォルダを対象として繰り返しを行う
# /dオプションをつける
$ for /d %%変数 in (セット) do コマンド
$ for /d %%d in (*) do (
$   echo dirname = %%d
$ )

# 指定したディレクトリに含まれるファイルに加えて
# サブディレクトリに含まれるファイルを含めて繰り返しを行う
# /rオプションをつける
$ for /r [パス] %%変数 in (セット) do コマンド
$ for /r d:\test %%f in (*.txt) do (
$   echo filename = %%f
$ )
```

### テキストファイルを読み込んで繰り返し処理を実行する

```powershell
# テキストファイルを読み込んで繰り返しを行う
# /fオプションをつける
$ for /f ["オプション"] %%変数 in (ファイル セット) do コマンド
$ for /f %%t in (address.txt) do (
$   echo token = %%t
$ )

# 行を区切り、〜番目の文字を出力する
# 区切りは、スペースorタブがある
# 番号のところは、token=2, token=2-4, token=2,3,4といった指定方法がある
$ for /f "token=番号" %%変数 in (ファイル セット) do コマンド
$ for /f "tokens="1,3,4" %%t in (address.txt) do (
$   echo token = %%t, %%u, %%v
$ )

# コメントとして行を飛ばす
# 読み飛ばすコメント行頭文字を指定する(例:!, ;など)
$ for /f "eol=コメント行頭文字" %%変数 in (ファイル セット) do コマンド
$ for /f "eol=! tokens="1-4" %%t in (address.txt) do (
$   echo token = %%t, %%u, %%v, %%w
$ )

# 分割する区切り文字を指定する
$ for /f "delims=区切り文字" %%変数 in (ファイル セット) do コマンド
$ for /f "delims=, tokens=1-3" %%t in (address.txt) do (
$   echo token = %%t, %%u, %%v
$ )

# ファイルの行頭でスキップする行数を指定する
$ for /f "skip=行数" %%変数 in (ファイル セット) do コマンド
$ for /f "skip=2 tokens=1-3" %%t in (address.txt) do (
$   echo token = %%t, %%u, %%v
$ )

# 空白が含まれるファイル名を指定する
# usebackqを指定する
$ for /f "usebackq" %%変数 in ("ファイル名") do コマンド
$ for /f "usebackq tokens=1-3" %%t in ("address test.txt") do (
$   echo token = %%t, %%u, %%v
$ )
```

## 9. バッチコマンド

### echo
* エコー機能(実行したコマンドを画面上に表示する機能)のON/OFFを切り替える。
* 任意の文字列を画面に表示する。

```powershell
# エコー機能について

# @をつけると、実行コマンドが非表示になる
$ @dir

# echoコマンドを使う場合、on/offを設定する
# echo offした後のコマンドは全て非表示となる
$ echo off
```

```powershell
# 文字列の表示について

# 「echo 文字列」で文字列を表示する
$ echo Hello

# 空白行、特殊文字を表示する場合は、echoの後に「.」をつける
$ echo. ^|
```

### rem
コメントを記述する。

```powershell
# コメントを書く
$ rem [コメント]
$ rem コメントだよ1
```

### pause
バッチ処理の実行を一時停止する。

```powershell
# バッチ処理の実行を一時停止する
$ pause
```

### call
指定したバッチファイルの処理を呼び出す。

```powershell
# 普通にバッチファイルを指定した場合と比べて、カレントディレクトリがそのままなので注意する
$ call バッチファイル名 引数
$ call bat2.bat

# 引数をつけるVer
$ set para1=Tokyo
$ set para2=25
$ call bat2.bat %para1% %para2%

# 呼び出したバッチでerrorlevelを設定する
# 0なら正常終了、1ならエラーあり
$ exit /b 数字 
$ exit /b 1 # これは呼び出されたバッチ
$ echo %errorlevel% # 呼び出したバッチで設定されたerrorlevelを呼び出し
```