こんなことを知りたい人へ向けて書いています
- 「for」コマンドでどんなことができるのか知りたい方
- 「for」コマンドの様々なオプションの機能や使い方を知りたい方
- Windowsコマンドプロンプトで繰り返し処理を実現したい方
目次
その他の関連しそうな記事
for文の役割
「for」コマンドの役割は、基本的に繰り返し処理を行うことです。
繰り返し処理といっても、様々な種類があり、処理は大きく分けて以下の4つがあります。それぞれ何に対して繰り返し処理を行うかが異なっています。
- 単に指定した回数だけ繰り返す
- 該当のファイル数だけ繰り返す
- 該当のフォルダ数だけ繰り返す
- ファイルの中身を読み込みながら繰り返す
です。それに伴って、「for」コマンドに指定するオプションが異なってきます。以下ではこの4つについて詳しく見ていきます。
指定した回数繰り返し処理「for /l」
まずは、決まった回数の処理を繰り返すfor文です。
これは、「/l」オプションを使用して以下のように書けます。
1 2 3 |
for /l %%[アルファベット1文字] in ([開始する数],[増加させる数],[終了する数]) do ( [処理内容] ) |
[アルファベット1文字]には、a~zもしくはA~Zの一文字を指定します。この一文字は何でも構いません。大文字と小文字は区別されますので注意が必要です。「%%A」と「%%a」は別のものとして扱われます。一般的なプログラムでは「a」や「i」を使うことが多いようです。
指定した「%%[アルファベット1文字]」には繰り返しを行う中で数値が格納されることになります。入る数値の初期値は[開始する数]に設定した値であり、その数から[終了する数]までを[増加させる数]だけ変化するさせながら[処理内容]を繰り返します。
実際に「for /l」を使ったバッチファイルの例「for_1.bat」を以下に示します。
1 2 3 4 5 6 7 |
@echo off rem %%aに0から9まで代入して繰り返す for /l %%a in (0, 1, 9) do ( rem %%aをコマンドプロンプトへ出力 echo %%a ) |
0から9まで「%%a」が+1ずつ変化しながら、do( )の中に記述されている「echo %%a」を繰り返し実行します。
したがって、コマンドプロンプトには以下の図のように0から9までの数字が連続して出力されます。
ファイルを対象とした繰り返し処理「for」
次に、ファイルを対象とした繰り返し処理です。これは以下のように書きます。
1 2 3 |
for %%[アルファベット1文字] in ([ファイル名]) do ( [処理内容] ) |
「for」文には何もオプションを指定していません。
[ファイル名]には対象にしたいファイルを指定します。ファイル「file.txt」を対象とするなら、「file.txt」とします。拡張子が「.txt」の全てのファイルを対象とするなら「*.txt」とします。全てのファイルを対象とするなら「*」といった感じです。
「%%[アルファベット1文字]」には、a~zもしくはA~Zの一文字を指定し、例えば「%%a」とした場合は「%%a」に[ファイル名]で指定したファイル名が一つずつ順番に入って「do ( )」の括弧内をループします。この括弧内には行いたい処理内容を記述します。
実際にコードを書くと以下のようになります。
1 2 3 4 5 6 |
@echo off rem 拡張子が「.txt」のファイルを対象に繰り返す for %%a in (*.txt) do ( echo %%a ) |
対象ファイルを「*.txt」をしており、バッチファイルが存在するフォルダ内のtxtファイルのファイル名を「%%a」に代入して、「echo %%a」を繰り返し行います。つなわち、フォルダ内の「*.txt」ファイルを全て表示させるプログラムとなっています。
これを「for_sample_1.bat」としてバッチファイルを作り、下の図のようなフォルダ内で実行してみましょう。
バッチファイル「for_sample_1.bat」と一緒に、datファイルが1つ、txtファイルが3つ存在します。
実行結果は以下の通りです。
3つのtxtファイルが表示されましたが、datファイルは表示されません。
このように、「%%a」にはtxtファイル名が一つずつ入り、do ( )の括弧内をループしていることが分かります。また、「in (*.txt)」としtxtファイルのみを対象に指定したため、拡張子が「.dat」のファイルはループの対象外になっていることも分かります。
ファイルを対象としたループ処理を使った応用例としては、ファイル名の前にその日の日付を付け加える処理を「第8章 ファイル名に日付を加える(改良編)」で紹介しています。
フォルダを対象とした繰り返し処理
今度は、ファイルではなくフォルダを対象とした繰り返し処理です。これは「for」の後に「/d」オプションを付けて、
1 2 3 |
for /d %%[アルファベット1文字] in ([フォルダ名]) do ( [処理内容] ) |
のように書きます。ほとんど前節のファイルを対象とした繰り返し処理と同様なので詳しい説明は不要でしょう。
[フォルダ名]には、「*」を指定するといまのフォルダ内、全てのフォルダに対して繰り返しが行われますし、例えば「test_*」と指定すれば、「test_」から始まるフォルダ名を持っているものだけが繰り返しの対象となります。
実際のコードは、
1 2 3 4 5 6 |
@echo off rem 「for /d」コマンドでフォルダを対象とした繰り返し for /d %%a in (folder_*) do ( echo %%a ) |
のような感じです。ここでは、バッチファイルが存在するフォルダ内のフォルダ名をコマンドプロンプト画面に出力しています。ただし、フォルダ名は先頭に「folder_」が付く物だけを対象にしています。
上記のバッチファイル「for_sample_2.bat」を以下のようなフォルダの下で動作を確認してみました。
フォルダ名は始まる文字が「directory_」と「folder_」の2種類が存在しています。
実行結果は以下の通りです。
予想通り「folder_」から始まるフォルダのみ繰り返しの対象となり、「%%a」に代入されて「echo %%a」コマンドで出力されました。「directory_」から始まるフォルダは対象外となっています。
ファイルの中身を対象とした繰り返し処理
ファイルの中身を対象とした繰り返し処理には「/f」オプションをつけたfor文を使用します。
1 2 3 |
for /f %%[アルファベット1文字] in ([ファイル名]) do ( [処理内容] ) |
これで、[ファイル名]に指定したファイルの中身を「%%[アルファベット1文字]」に代入しながら、ループを回していきます。
以下のようなバッチファイル「for_sample_3.bat」を考えましょう。
1 2 3 4 5 6 |
@echo off rem 「file.txt」ファイルの内容を読み込みながら繰り返す for /f %%a in (file.txt) do ( echo %%a ) |
「file.txt」ファイルの内容を読み込みながら繰り返し処理を行い、コマンドプロンプト画面に出力するバッチファイルです。このバッチファイルで「file.txt」ファイルの内容が、
の場合、実行結果は以下のようになります。
このように、ファイル内容を一行ずつ読み込めていることが分かります。
ただし、注意すべきは、「%%[アルファベット1文字]」には、スペースで区切られているところまでが代入される点です。例えば、読み込むファイルの内容の1行に「yahoo mail」という行があったとします。これだと、「%%[アルファベット1文字]」には、「yahoo」としか入りません。
実際に試してみましょう。先ほどのバッチファイルに今度は以下のようなファイルを読み込ませてみます。
バッチファイルを実行すると、以下のようになります。
このように、はじめのスペースまでしか読み込めていません。2列目の「mail」まで読み込む方法は後に紹介します。
二列目以降を取り出す
「file.txt」ファイルの内容が、
であり、二列目の数字まで読み込んで出力したい場合は、「tokens=」を使用すれば、「%%b」が自動的に二列目に割り当てられます。以下、バッチファイル例です。
1 2 3 4 5 6 |
@echo off rem 「token」を使って二列目まで読み込むことを宣言 for /f "tokens=1,2" %%a in (file.txt) do ( echo %%a %%b ) |
5行目のループの中に「%%b」を使っていることに注目です。この出力は以下の通りです。
「%%a」には1列目のアルファベットが、「%%b」には二列目の数字が入っていることが分かります。
三列目以上ある場合も同様に「”tokens=1,2,3…”」に対して「%%a %%b %%c…」とすればよいです。
また、はじめのアルファベットを「%%i」と指定した場合は2列目以降を参照する場合「%%j, %%k…」を使用します。すなわち、はじめに使用したアルファベットを基準に、その後はアルファベット順に使用されていきます。以下は3列分読み込んで出力するバッチファイルの例です。
1 2 3 4 5 6 |
@echo off rem 「token」を使って3列目まで読み込むことを宣言 for /f "tokens=1,2,3" %%i in (file.txt) do ( echo %%i %%j %%k ) |
ちなみに、「tokens=[数字]」の[数字]が連番の場合は「tokens=1-9」のように書くことができます。従って、以下のバッチファイルは上のバッチファイルと同様の動きをします。
1 2 3 4 5 6 |
」の数字が連番の場合"]@echo off rem 「-」を使って読み込む列の範囲を指定 for /f "tokens=1-3" %%i in (file.txt) do ( echo %%i %%j %%k ) |
区切り文字を指定する
「file.txt」ファイルの内容が、
とスペース以外の文字で区切られている場合は、区切り文字を「delims=[区切り文字]」に指定することで、列を分割することができます。
ここでは、コンマ「,」で区切られているので、「delims=,」を指定します。
1 2 3 4 5 6 |
@echo off rem 「delims」を使って区切り文字を指定 for /f "tokens=1,2 delims=," %%a in (file.txt) do ( echo %%a %%b ) |
ただし注意すべきは、いま「delims=,」とだけ指定しているため、スペースが区切り文字扱いになっていないということです。スペースも「,」に加えて区切り文字として扱いたい場合には、「delims=, 」(分かりにくいですが、「,」のあとにスペースが入っています)のようにスペースも指定してあげる必要があります。
ファイルの内容がコンマ以外で区切られている場合も同様にその区切り文字を指定すれば、列を分割できます。例えば「file.txt」が、
となっていれば、「delims=:」とします。
また、複数の区切り文字を組み合わせることもできます。以下のバッチファイルは区切り文字にコンマ「,」、スペース「 」、コロン「:」を指定した例です。
1 2 3 4 5 6 |
@echo off rem 「delims」を使って区切り文字「,」、スペース、「:」の3つを指定 for /f "tokens=1,2 delims=, :" %%a in (file.txt) do ( echo %%a %%b ) |
「delims」オプションを使った応用例としては、「第9章 ファイル内の文字列を置換」で詳しく紹介していますの参考にして下さい。
「for」コマンドによるファイル内容からの文字列の読み込みに関しては、「ファイルから文字列を読み込む -やりたいことから検索-」でより詳しく説明しています。
こんばんは
いつも勉強させて頂いております。
この度、Teratermマクロを同時に実行してサーバとスイッチのログを取得するマクロを作成しました。
このマクロが50個ほどあり、時間の関係からこれらを同時に実行する必要があります。
これらのマクロファイルは、個別のファイルを直接クリックして開いた場合は様々な選択肢を選びながら作業者の選択に応じたログを取得するのですが、
全てを同時に起動する際は毎回決まったログを取りにいきますので選択は不要です。
その全て同時に起動する際にbatファイルを用いて起動しようと思い、
貴サイトを見て以下のようなバッチファイルを作成しました。
@echo off
for %%a in (*.ttl) do (
echo %%a *
)
おかげさまで、このバッチファイルでフォルダ内の全てのttlファイルは実行されるのですが、
50個全ての選択肢を3つほど選ばなければならず合計150クリックの作業が追加されてしまいます。
その選択肢を回避するための引数を渡したいのですが、
バッチファイルの書き方が悪いのか、Teratermが悪いのか不明なのですがTeraterm側に引数が渡りません。
バッチファイルには*の部分に2つほど記入しましたがどちらも渡らず、
param1というものでTeratermマクロファイル名だけが表示され、あとは空白でした。
これをきちんと渡すには現在の位置への記入で正しいでしょうか。
それともまた別の場所に書くべきなのでしょうか。
PowerShellも検討しましたが、門戸の広いバッチでぜひともやりたいと考えています。
Teratermのことまで聞いてしまい非常に恐縮なのですがご教授頂けないでしょうか。
よろしくお願いします。
コメントありがとうございます。
Windowsバッチファイルの引数の渡し方としては、合っていますのでTeratermに引数として渡す際にTeraterm側の決まりがあるのかもしれません。
Teratermに関してはあまり詳しくないのですが、よろしければ実際コードについて詳しく教えていただけませんか?
「*.ttl」ファイルの中にどのような記述がされているかわかれば、何か解決策を提案できるかもしれません。
ここに載るのが都合が悪い場合は「お問い合わせ」から直接ご連絡くださっても構いません。
よろしくお願いいたします。
こんばんは
お返事ありがとうございました。
お返事頂いて申し訳ないのですが自己解決しました。
原因は、Teratermのexeまでのフルパスを記載していないことでした。
ttlをダブルクリックするとTeratermマクロが開くのでそれでよしとしていましたが、
windows内部の関連付けがキチンとできておらず、ftypeやassocで.ttlを調べたところ
登録すらされていないありさまでした。
登録しようと思いましたがどうも上手くいかず、Teratemのexeの位置までのフルパスを記載することで乗り切ることとしました。
echo %%a *
を↓このようにしました。
start “” “C:¥Program Files (x86)¥teraterm¥ttpmacro.exe” %%a *
大抵のサイトがここをechoで記載し、また、Teraterm自体は起動していますので、
exeの位置を指定しないといけないとは夢にも思いませんでした。
プログラムは奥が深いですね。
また、引数を渡す先のTeratermマクロ自体の位置も記載しておかなければならず、
そのことも理解できていなかったためどうにも上手くいかず質問させて頂きました。
同じフォルダにあるので大丈夫と思ってましたがダメだったようです。
これからもbatについて学ばないといけないことが多々ありますので、
これからも貴サイトを参考にさせて頂きたいと思います。
またなにか分からないことが出てきましたら質問させて頂きますので、
その際はよろしくお願いします。