3件のコメント

Dos、バッチ、コマンドプロンプトで仕事をしなければいけない不幸な人に送るforコマンド解説

今はもうOSに標準でPowerShellが搭載されている時代です。Windows 2000世代からはWSHが標準搭載されバッチファイルから解放されました。Windows 7, Windows Server 2008ではPowerShellが標準搭載されWSHからも解放されました。.net frameworkも使いつつオブジェクト指向のスクリプトが書ける、そんないい時代になりました。めでたしめでたし…とはいかないのがこの業界です。残念ながら最新のOS上でいまだにバッチファイルを書かなければならない仕事、未だに仮想化されたWindowsNTの面倒を見なければいけない仕事などが存在するのが現実です。

バッチファイルでは実際のところ相当生産性が低いのですが、そんな中で異彩を放つコマンド”for”。その名前からはただの繰り返しコマンドに思えるのですが、実は恐ろしい力を秘めています。実際の所バッチファイルでちょっと複雑なことをやろうと思うとforを効果的に使わないといけません。今回は未だにバッチファイルを書かなければいけない不幸な人のためにforコマンドのTips集をお届けします。

forコマンドのヘルプから読み取れる「できること」

forコマンドは色々な事ができるコマンドなのですが、まじまじとヘルプを見たことが無い人も多いと思います。以下はWindows7のforコマンドのヘルプです。

指定されたコマンドをファイル セットの各ファイルに対して実行します。

 


 

FOR %変数 IN (セット) DO コマンド [コマンドパラメーター]

 


 

  %変数     単一文字の置き換え可能なパラメーターを指定します。

 

  (セット)  ファイル セットを指定します。ワイルドカードを使用できます。

 

  コマンド  各ファイルごとに実行するコマンドを指定します。

 

  コマンドパラメーター

 

            指定されたコマンドのパラメーターまたはスイッチを指定します。

 


 

バッチ プログラムで FOR コマンドを使用するときは、%変数の代わりに、

 

%%変数を使用してください。変数名では大文字と小文字が区別されるため、

 

%i と %I は異なります。

 


 

コマンド拡張機能を有効にすると、次の FOR コマンドの追加形式

 

がサポートされるようになります:

 


 

FOR /D %変数 IN (セット) DO コマンド [コマンド パラメーター]

 


 

    セットがワイルドカードを含む場合は、ファイル名ではなくディレクトリ名

 

    の一致を指定します。

 


 

FOR /R [[ドライブ:]パス] %変数 IN (セット) DO コマンド [コマンド パラメーター]

 


 

    [ドライブ:]パスから始めて、ツリーの各ディレクトリで FOR 文を実行し

 

    ます。/R の後にディレクトリが指定されていない場合は、現在の

 

    ディレクトリが使用されます。セットが単一のピリオド (.) である場合は、

 

    ディレクトリ ツリーの列挙だけを行います。

 


 

FOR /L %変数 IN (開始,ステップ,終了) DO コマンド [コマンド パラメーター]

 


 

    セットは、ステップの量ごとに変化する開始から終了までの数列です。

 

    たとえば、(1,1,5) は 1 2 3 4 5、(5,-1,1) は (5 4 3 2 1) という数列に

 

    なります。

 


 

FOR /F ["オプション"] %変数 IN (ファイル セット) DO コマンド

 

       [コマンド パラメーター]

 

FOR /F ["オプション"] %変数 IN ("文字列") DO コマンド [コマンド パラメーター]

 

FOR /F ["オプション"] %変数 IN ('コマンド') DO コマンド [コマンド パラメーター]

 


 

    または usebackq オプションの場合:

 


 

FOR /F ["オプション"] %変数 IN (ファイル セット) DO コマンド

 

       [コマンド パラメーター]

 

FOR /F ["オプション"] %変数 IN ('文字列') DO コマンド [コマンド パラメーター]

 

FOR /F ["オプション"] %変数 IN (`コマンド`) DO コマンド [コマンド パラメーター]

 


 

    ファイル セットは、1 つ以上のファイル名です。各ファイルが開かれ、

 

    読み取られ、処理されてから、ファイル セットの次のファイルに進みます。

 

    処理では、ファイルの読み取り、個々のテキスト行への分割と、0 個以上の

 

    トークンへの解析が行われます。その後、見つかったトークン文字列を変数値に

 

    設定して for ループの本体が呼び出されます。既定では、/F は、各ファイルの

 

    各行から、空白で区切られた最初のトークンを取得して渡します。空白行は

 

    スキップされます。既定の解析動作を変更するには、省略可能な "オプション"

 

    パラメーターを指定します。これは、異なる解析オプションを指定する 1 つ以上の

 

    キーワードを含む、引用符で囲まれた文字列です。キーワードは、次のとおりです:

 


 

        eol=c           - 行末のコメント文字を指定します (1 文字)。

 

        skip=n          - ファイルの先頭でスキップする行数を指定します。

 

        delims=xxx      - 区切り文字のセットを指定します。

 

                          これは、既定の区切り文字であるスペースとタブを

 

                          置き換えます。

 

        tokens=x,y,m-n  - 各繰り返しに対して、各行から for 本体に渡す

 

                          トークンを指定します。これにより、追加の変数名が

 

                          割り当てられます。

 

                          m-n の形式は範囲で、m 番目から n 番目の

 

                          トークンを指定します。

 

                          tokens= 文字列の最後の文字がアスタリスクである場合は、

 

                          追加の変数が割り当てられ、最後のトークンが解析された

 

                          後、行に含まれている残りのテキストを受け取ります。

 

        usebackq        - 次の新しい表示形式を指定します。

 

                          逆引用符で囲まれた文字列がコマンドとして実行され、

 

                          一重引用符で囲まれた文字列がリテラル文字列コマンドに

 

                          なり、ファイル セットのファイル名を二重引用符で

 

                          囲めるようになります。

 


 

    例を参考にしてください:

 


 

FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k

 


 

    この例は、myfile.txt の各行を解析します。セミコロンで始まる行を無視し、

 

    各行の 2 番目と 3 番目のトークンを for 本体に渡します。

 

    トークンは、コンマまたはスペースで区切られています。

 

    for 本体の文が %i で 2 番目のトークンを、%j で 3 番目のトークンを取得し、

 

    %k で 3 番目以降のすべてのトークンを取得していることに

 

    注意してください。

 

    スペースを含むファイル名に対しては、二重引用符でファイル名を引用する

 

    必要があります。

 

    この方法で二重引用符を使うためには、usebackq オプションも

 

    使わなければなりません。

 

    使わなければ、二重引用符はリテラル文字列の定義として

 

    解釈され、解析されます。

 


 

    %i は for 文で明示的に宣言され、%j と %k は tokens= オプションで暗黙的に

 

    宣言されています。

 

    tokens= 行を使って 26 個までのトークンを指定できますが、

 

    文字 'z' または 'Z' よりも高い変数を宣言することはできません。FOR 変数名は

 

    単一の文字で、大文字と小文字を区別し、グローバルなものであり、一度に

 

    アクティブにできるのは合計 52 個までです。

 


 

    また、かっこで囲んだファイル セットを一重引用符で囲み、文字列にすることに

 

    より、即時の文字列に対する FOR /F 解析ロジックを使うこともできます。

 

    これは、ファイルからの単一入力行として処理されます。

 


 

    最後に、FOR /F コマンドを使って、コマンド出力を解析することができます。

 

    かっこの中のファイル セットを逆引用符で囲みます。この文字列は、コマンド

 

    ラインとして子 CMD.EXE に渡されます。出力はメモリにキャプチャされ、

 

    ファイルのように解析されます。

 

    例:

 


 

      FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i

 


 

    この例は、現在の環境の環境変数名を列挙します。

 


 

また、FOR 変数参照の置換も拡張されました。

 

次のオプション構文を使うことができます:

 


 

    %~I         - すべての引用句 (") を削除して、%I を展開します。

 

    %~fI        - %I を完全修飾パス名に展開します。

 

    %~dI        - %I をドライブ文字だけに展開します。

 

    %~pI        - %I をパス名だけに展開します。

 

    %~nI        - %I をファイル名だけに展開します。

 

    %~xI        - %I をファイル拡張子だけに展開します。

 

    %~sI        - 展開されたパスは短い名前だけを含みます。

 

    %~aI        - %I をファイルの属性に展開します。

 

    %~tI        - %I ファイルの日付/時刻に展開します。

 

    %~zI        - %I ファイルのサイズに展開します。

 

    %~$PATH:I   - PATH 環境変数に指定されているディレクトリを

 

                   検索し、最初に見つかった完全修飾名に %I を

 

                   展開します。

 

                   環境変数名が定義されていない場合、または検索

 

                   してもファイルが見つからなかった場合は、この

 

                   修飾子を指定すると空の文字列に展開されます。

 


 

修飾子を組み合わせて、複合結果を得ることもできます:

 


 

    %~dpI       - %I をドライブ文字とパスだけに展開します。

 

    %~nxI       - %I をファイル名と拡張子だけに展開します。

 

    %~fsI       - %I を完全なパスと短い名前だけに展開します。

 

    %~dp$PATH:I - PATH 環境変数に指定されているディレクトリを

 

                   検索して %I を探し、最初に見つかったファイル

 

                   のドライブ文字とパスだけに展開します。

 

    %~ftzaI     - %I を DIR コマンドの出力行のように展開します。

 


 

上の例の %I と PATH は、他の有効な値で置き換えることができます。

 

%~ 構文は、有効な FOR 変数名によって区切られます。%I のような大

 

文字の変数を使うと読み取りやすく、大文字と小文字を区別しない修飾子

 

との混乱を避けることができます。

 

ヘルプの長さにまず驚かされますが、「指定されたコマンドをファイル セットの各ファイルに対して実行します。」と、ある通り、基本的には複数のファイルに対してコマンドを実行することが出来るコマンドということになっているようです。

FOR /D %変数 IN (セット) DO コマンド [コマンド パラメーター]

 


 

    セットがワイルドカードを含む場合は、ファイル名ではなくディレクトリ名

 

    の一致を指定します。

 

さらに上記のようにディレクトリに対しても処理を行えることがわかります。

FOR /R [[ドライブ:]パス] %変数 IN (セット) DO コマンド [コマンド パラメーター]

 


 

    [ドライブ:]パスから始めて、ツリーの各ディレクトリで FOR 文を実行し

 

    ます。/R の後にディレクトリが指定されていない場合は、現在の

 

    ディレクトリが使用されます。セットが単一のピリオド (.) である場合は、

 

    ディレクトリ ツリーの列挙だけを行います。

 

ディレクトリツリーに対して再帰的に処理も行えるようです。

FOR /L %変数 IN (開始,ステップ,終了) DO コマンド [コマンド パラメーター]

 


 

    セットは、ステップの量ごとに変化する開始から終了までの数列です。

 

    たとえば、(1,1,5) は 1 2 3 4 5、(5,-1,1) は (5 4 3 2 1) という数列に

 

    なります。

 

もちろん普通のプログラム言語のように数を変化させながら繰り返し処理もできます。

FOR /F ["オプション"] %変数 IN (ファイル セット) DO コマンド

 

       [コマンド パラメーター]

 

FOR /F ["オプション"] %変数 IN ("文字列") DO コマンド [コマンド パラメーター]

 

FOR /F ["オプション"] %変数 IN ('コマンド') DO コマンド [コマンド パラメーター]

 


 

    または usebackq オプションの場合:

 


 

FOR /F ["オプション"] %変数 IN (ファイル セット) DO コマンド

 

       [コマンド パラメーター]

 

FOR /F ["オプション"] %変数 IN ('文字列') DO コマンド [コマンド パラメーター]

 

FOR /F ["オプション"] %変数 IN (`コマンド`) DO コマンド [コマンド パラメーター]

 

文字列やコマンドの結果に対しても処理ができちゃいます。

ファイル セットは、1 つ以上のファイル名です。各ファイルが開かれ、

 

読み取られ、処理されてから、ファイル セットの次のファイルに進みます。

 

処理では、ファイルの読み取り、個々のテキスト行への分割と、0 個以上の

 

トークンへの解析が行われます。その後、見つかったトークン文字列を変数値に

 

設定して for ループの本体が呼び出されます。既定では、/F は、各ファイルの

 

各行から、空白で区切られた最初のトークンを取得して渡します。空白行は

 

スキップされます。

 

さらにファイルに対してはその内容を読み取り行ごとに処理したり、さらに”トークンへの解析”までしてくれちゃいます。

既定の解析動作を変更するには、省略可能な "オプション"

 

    パラメーターを指定します。これは、異なる解析オプションを指定する 1 つ以上の

 

    キーワードを含む、引用符で囲まれた文字列です。キーワードは、次のとおりです:

 


 

        eol=c           - 行末のコメント文字を指定します (1 文字)。

 

        skip=n          - ファイルの先頭でスキップする行数を指定します。

 

        delims=xxx      - 区切り文字のセットを指定します。

 

                          これは、既定の区切り文字であるスペースとタブを

 

                          置き換えます。

 

        tokens=x,y,m-n  - 各繰り返しに対して、各行から for 本体に渡す

 

                          トークンを指定します。これにより、追加の変数名が

 

                          割り当てられます。

 

                          m-n の形式は範囲で、m 番目から n 番目の

 

                          トークンを指定します。

 

                          tokens= 文字列の最後の文字がアスタリスクである場合は、

 

                          追加の変数が割り当てられ、最後のトークンが解析された

 

                          後、行に含まれている残りのテキストを受け取ります。

 

        usebackq        - 次の新しい表示形式を指定します。

 

                          逆引用符で囲まれた文字列がコマンドとして実行され、

 

                          一重引用符で囲まれた文字列がリテラル文字列コマンドに

 

                          なり、ファイル セットのファイル名を二重引用符で

 

                          囲めるようになります。

 

コメント文字の指定や、スキップする行数の指定まで出来ますし、区切り文字の指定、本体に渡すトークン指定までできちゃいます。

また、FOR 変数参照の置換も拡張されました。

 

次のオプション構文を使うことができます:

 


 

    %~I         - すべての引用句 (") を削除して、%I を展開します。

 

    %~fI        - %I を完全修飾パス名に展開します。

 

    %~dI        - %I をドライブ文字だけに展開します。

 

    %~pI        - %I をパス名だけに展開します。

 

    %~nI        - %I をファイル名だけに展開します。

 

    %~xI        - %I をファイル拡張子だけに展開します。

 

    %~sI        - 展開されたパスは短い名前だけを含みます。

 

    %~aI        - %I をファイルの属性に展開します。

 

    %~tI        - %I ファイルの日付/時刻に展開します。

 

    %~zI        - %I ファイルのサイズに展開します。

 

    %~$PATH:I   - PATH 環境変数に指定されているディレクトリを

 

                   検索し、最初に見つかった完全修飾名に %I を

 

                   展開します。

 

                   環境変数名が定義されていない場合、または検索

 

                   してもファイルが見つからなかった場合は、この

 

                   修飾子を指定すると空の文字列に展開されます。

 


 

修飾子を組み合わせて、複合結果を得ることもできます:

 


 

    %~dpI       - %I をドライブ文字とパスだけに展開します。

 

    %~nxI       - %I をファイル名と拡張子だけに展開します。

 

    %~fsI       - %I を完全なパスと短い名前だけに展開します。

 

    %~dp$PATH:I - PATH 環境変数に指定されているディレクトリを

 

                   検索して %I を探し、最初に見つかったファイル

 

                   のドライブ文字とパスだけに展開します。

 

    %~ftzaI     - %I を DIR コマンドの出力行のように展開します。

 

さらにさらに変数の置換機能まであります。

 

…。さすがはforコマンドですね。「それは別のコマンドを用意したほうがいいんじゃないのか?」という機能まで満載されています。コマンドプロンプト、バッチファイルでは他の機能が貧弱なだけにforコマンドを多用することになります。

では、いくつか例を実行してみたいと思います。この手のものは「習うより慣れろ」ですから是非コマンドプロンプトを立ち上げて一緒に操作しながら読んでもらえればと思います。

ループ処理

まずは、テスト用のディレクトリを作成します。

 1: mkdir c:\fortest

 

 2: cd c:\fortest

 

テスト用のテキストファイルを用意しましょう。適当に10個程度にしましょうか。せっかくですのでこれもforコマンドで作成してみましょう。

以下のように実行すると10個のテキストファイルが生成されます。

 1: c:\fortest>for /L %i IN (1,1,10) DO echo sample%i > sample%i.txt

 

 2:

 

 3: c:\fortest>echo sample1  1>sample1.txt

 

 4:

 

 5: c:\fortest>echo sample2  1>sample2.txt

 

 6:

 

 7: c:\fortest>echo sample3  1>sample3.txt

 

 8:

 

 9: c:\fortest>echo sample4  1>sample4.txt

 

 10:

 

 11: c:\fortest>echo sample5  1>sample5.txt

 

 12:

 

 13: c:\fortest>echo sample6  1>sample6.txt

 

 14:

 

 15: c:\fortest>echo sample7  1>sample7.txt

 

 16:

 

 17: c:\fortest>echo sample8  1>sample8.txt

 

 18:

 

 19: c:\fortest>echo sample9  1>sample9.txt

 

 20:

 

 21: c:\fortest>echo sample10  1>sample10.txt

 

/Lオプションを使用するとこのように変数の中に数字を入れつつ、コマンドを繰り返し実行させることができます。この例では変数%iに対して1から1つづつ値をふやしながら10になるまで「echo sample%1 > sample%i.txt」というコマンドを実行させています。これはいわゆるプログラム言語でいうところのfor文と同じような感じなので理解しやすいのではないかと思います。

ファイル名の取得

次はファイル名の取得の例です。以下のように実行できます。

 1: c:\fortest>for %i IN (*.txt) DO @echo %i

 

 2: sample1.txt

 

 3: sample10.txt

 

 4: sample2.txt

 

 5: sample3.txt

 

 6: sample4.txt

 

 7: sample5.txt

 

 8: sample6.txt

 

 9: sample7.txt

 

 10: sample8.txt

 

 11: sample9.txt

 

オプションを付けずにforを実行すると、パターンにマッチするファイル名を取得して変数に1つづつ値を入れつつ、コマンドを実行させることができます。このパターンマッチにはディレクトリ(フォルダ)はマッチしません。以下のように確認できます。

 1: c:\fortest>for /L %i IN (1,1,10) DO mkdir dir%i

 

 2:

 

 3: c:\fortest>mkdir dir1

 

 4:

 

 5: c:\fortest>mkdir dir2

 

 6:

 

 7: c:\fortest>mkdir dir3

 

 8:

 

 9: c:\fortest>mkdir dir4

 

 10:

 

 11: c:\fortest>mkdir dir5

 

 12:

 

 13: c:\fortest>mkdir dir6

 

 14:

 

 15: c:\fortest>mkdir dir7

 

 16:

 

 17: c:\fortest>mkdir dir8

 

 18:

 

 19: c:\fortest>mkdir dir9

 

 20:

 

 21: c:\fortest>mkdir dir10

 

 22:

 

 23: c:\fortest>for %i IN (*) DO @echo %i

 

 24: sample1.txt

 

 25: sample10.txt

 

 26: sample2.txt

 

 27: sample3.txt

 

 28: sample4.txt

 

 29: sample5.txt

 

 30: sample6.txt

 

 31: sample7.txt

 

 32: sample8.txt

 

 33: sample9.txt

 

 34:

 

 35: c:\fortest>dir

 

 36:  ドライブ C のボリューム ラベルがありません。

 

 37:  ボリューム シリアル番号は C0AF-1B4F です

 

 38:

 

 39:  c:\fortest のディレクトリ

 

 40:

 

 41: 2012/03/15  21:59    <DIR>          .

 

 42: 2012/03/15  21:59    <DIR>          ..

 

 43: 2012/03/15  21:59    <DIR>          dir1

 

 44: 2012/03/15  21:59    <DIR>          dir10

 

 45: 2012/03/15  21:59    <DIR>          dir2

 

 46: 2012/03/15  21:59    <DIR>          dir3

 

 47: 2012/03/15  21:59    <DIR>          dir4

 

 48: 2012/03/15  21:59    <DIR>          dir5

 

 49: 2012/03/15  21:59    <DIR>          dir6

 

 50: 2012/03/15  21:59    <DIR>          dir7

 

 51: 2012/03/15  21:59    <DIR>          dir8

 

 52: 2012/03/15  21:59    <DIR>          dir9

 

 53: 2012/03/15  21:55                10 sample1.txt

 

 54: 2012/03/15  21:55                11 sample10.txt

 

 55: 2012/03/15  21:55                10 sample2.txt

 

 56: 2012/03/15  21:55                10 sample3.txt

 

 57: 2012/03/15  21:55                10 sample4.txt

 

 58: 2012/03/15  21:55                10 sample5.txt

 

 59: 2012/03/15  21:55                10 sample6.txt

 

 60: 2012/03/15  21:55                10 sample7.txt

 

 61: 2012/03/15  21:55                10 sample8.txt

 

 62: 2012/03/15  21:55                10 sample9.txt

 

 63:               10 個のファイル                 101 バイト

 

 64:               12 個のディレクトリ  142,859,378,688 バイトの空き領域

 

ディレクトリ名の取得

/Dオプションをつけて実行すると、ディレクトリのみがパターンにマッチするようになります。

 1: c:\fortest>for /D %i IN (*) DO @echo %i

 

 2: dir1

 

 3: dir10

 

 4: dir2

 

 5: dir3

 

 6: dir4

 

 7: dir5

 

 8: dir6

 

 9: dir7

 

 10: dir8

 

 11: dir9

 

再帰処理

ディレクトリを指定し、そこから下位のディレクトリのそれぞれでforコマンドを実行させることができます。ちょっとディレクトリ、ファイルを準備してみます。

 1: c:\fortest>for /L %i IN (1,1,10) DO echo sample%i > .\dir%i\sample%i.txt

 

 2:

 

 3: c:\fortest>echo sample1  1>.\dir1\sample1.txt

 

 4:

 

 5: c:\fortest>echo sample2  1>.\dir2\sample2.txt

 

 6:

 

 7: c:\fortest>echo sample3  1>.\dir3\sample3.txt

 

 8:

 

 9: c:\fortest>echo sample4  1>.\dir4\sample4.txt

 

 10:

 

 11: c:\fortest>echo sample5  1>.\dir5\sample5.txt

 

 12:

 

 13: c:\fortest>echo sample6  1>.\dir6\sample6.txt

 

 14:

 

 15: c:\fortest>echo sample7  1>.\dir7\sample7.txt

 

 16:

 

 17: c:\fortest>echo sample8  1>.\dir8\sample8.txt

 

 18:

 

 19: c:\fortest>echo sample9  1>.\dir9\sample9.txt

 

 20:

 

 21: c:\fortest>echo sample10  1>.\dir10\sample10.txt

 

 22:

 

 23: c:\fortest>dir /s

 

 24:  ドライブ C のボリューム ラベルがありません。

 

 25:  ボリューム シリアル番号は C0AF-1B4F です

 

 26:

 

 27:  c:\fortest のディレクトリ

 

 28:

 

 29: 2012/03/15  21:59    <DIR>          .

 

 30: 2012/03/15  21:59    <DIR>          ..

 

 31: 2012/03/15  22:05    <DIR>          dir1

 

 32: 2012/03/15  22:05    <DIR>          dir10

 

 33: 2012/03/15  22:05    <DIR>          dir2

 

 34: 2012/03/15  22:05    <DIR>          dir3

 

 35: 2012/03/15  22:05    <DIR>          dir4

 

 36: 2012/03/15  22:05    <DIR>          dir5

 

 37: 2012/03/15  22:05    <DIR>          dir6

 

 38: 2012/03/15  22:05    <DIR>          dir7

 

 39: 2012/03/15  22:05    <DIR>          dir8

 

 40: 2012/03/15  22:05    <DIR>          dir9

 

 41: 2012/03/15  21:55                10 sample1.txt

 

 42: 2012/03/15  21:55                11 sample10.txt

 

 43: 2012/03/15  21:55                10 sample2.txt

 

 44: 2012/03/15  21:55                10 sample3.txt

 

 45: 2012/03/15  21:55                10 sample4.txt

 

 46: 2012/03/15  21:55                10 sample5.txt

 

 47: 2012/03/15  21:55                10 sample6.txt

 

 48: 2012/03/15  21:55                10 sample7.txt

 

 49: 2012/03/15  21:55                10 sample8.txt

 

 50: 2012/03/15  21:55                10 sample9.txt

 

 51:               10 個のファイル                 101 バイト

 

 52:

 

 53:  c:\fortest\dir1 のディレクトリ

 

 54:

 

 55: 2012/03/15  22:05    <DIR>          .

 

 56: 2012/03/15  22:05    <DIR>          ..

 

 57: 2012/03/15  22:05                10 sample1.txt

 

 58:                1 個のファイル                  10 バイト

 

 59:

 

 60:  c:\fortest\dir10 のディレクトリ

 

 61:

 

 62: 2012/03/15  22:05    <DIR>          .

 

 63: 2012/03/15  22:05    <DIR>          ..

 

 64: 2012/03/15  22:05                11 sample10.txt

 

 65:                1 個のファイル                  11 バイト

 

 66:

 

 67:  c:\fortest\dir2 のディレクトリ

 

 68:

 

 69: 2012/03/15  22:05    <DIR>          .

 

 70: 2012/03/15  22:05    <DIR>          ..

 

 71: 2012/03/15  22:05                10 sample2.txt

 

 72:                1 個のファイル                  10 バイト

 

 73:

 

 74:  c:\fortest\dir3 のディレクトリ

 

 75:

 

 76: 2012/03/15  22:05    <DIR>          .

 

 77: 2012/03/15  22:05    <DIR>          ..

 

 78: 2012/03/15  22:05                10 sample3.txt

 

 79:                1 個のファイル                  10 バイト

 

 80:

 

 81:  c:\fortest\dir4 のディレクトリ

 

 82:

 

 83: 2012/03/15  22:05    <DIR>          .

 

 84: 2012/03/15  22:05    <DIR>          ..

 

 85: 2012/03/15  22:05                10 sample4.txt

 

 86:                1 個のファイル                  10 バイト

 

 87:

 

 88:  c:\fortest\dir5 のディレクトリ

 

 89:

 

 90: 2012/03/15  22:05    <DIR>          .

 

 91: 2012/03/15  22:05    <DIR>          ..

 

 92: 2012/03/15  22:05                10 sample5.txt

 

 93:                1 個のファイル                  10 バイト

 

 94:

 

 95:  c:\fortest\dir6 のディレクトリ

 

 96:

 

 97: 2012/03/15  22:05    <DIR>          .

 

 98: 2012/03/15  22:05    <DIR>          ..

 

 99: 2012/03/15  22:05                10 sample6.txt

 

 100:                1 個のファイル                  10 バイト

 

 101:

 

 102:  c:\fortest\dir7 のディレクトリ

 

 103:

 

 104: 2012/03/15  22:05    <DIR>          .

 

 105: 2012/03/15  22:05    <DIR>          ..

 

 106: 2012/03/15  22:05                10 sample7.txt

 

 107:                1 個のファイル                  10 バイト

 

 108:

 

 109:  c:\fortest\dir8 のディレクトリ

 

 110:

 

 111: 2012/03/15  22:05    <DIR>          .

 

 112: 2012/03/15  22:05    <DIR>          ..

 

 113: 2012/03/15  22:05                10 sample8.txt

 

 114:                1 個のファイル                  10 バイト

 

 115:

 

 116:  c:\fortest\dir9 のディレクトリ

 

 117:

 

 118: 2012/03/15  22:05    <DIR>          .

 

 119: 2012/03/15  22:05    <DIR>          ..

 

 120: 2012/03/15  22:05                10 sample9.txt

 

 121:                1 個のファイル                  10 バイト

 

 122:

 

 123:      ファイルの総数:

 

 124:               20 個のファイル                 202 バイト

 

 125:               32 個のディレクトリ  142,869,659,648 バイトの空き領域

 

これで、カレントディレクトリにはディレクトリが10個、ファイルが10個。サブディレクトリにはそれぞれファイルが1個づつという状態になりました。現在のディレクトリ以下にある.txtという拡張子を持つファイルを全て表示してみます。

 1: c:\fortest>for /R %i IN (*.txt) DO @echo %i

 

 2: c:\fortest\sample1.txt

 

 3: c:\fortest\sample10.txt

 

 4: c:\fortest\sample2.txt

 

 5: c:\fortest\sample3.txt

 

 6: c:\fortest\sample4.txt

 

 7: c:\fortest\sample5.txt

 

 8: c:\fortest\sample6.txt

 

 9: c:\fortest\sample7.txt

 

 10: c:\fortest\sample8.txt

 

 11: c:\fortest\sample9.txt

 

 12: c:\fortest\dir1\sample1.txt

 

 13: c:\fortest\dir10\sample10.txt

 

 14: c:\fortest\dir2\sample2.txt

 

 15: c:\fortest\dir3\sample3.txt

 

 16: c:\fortest\dir4\sample4.txt

 

 17: c:\fortest\dir5\sample5.txt

 

 18: c:\fortest\dir6\sample6.txt

 

 19: c:\fortest\dir7\sample7.txt

 

 20: c:\fortest\dir8\sample8.txt

 

 21: c:\fortest\dir9\sample9.txt

 

ディレクトリ名だけ表示するには以下のようにします。

 1: c:\fortest>for /R %i IN (.) DO @echo %i

 

 2: c:\fortest\.

 

 3: c:\fortest\dir1\.

 

 4: c:\fortest\dir10\.

 

 5: c:\fortest\dir2\.

 

 6: c:\fortest\dir3\.

 

 7: c:\fortest\dir4\.

 

 8: c:\fortest\dir5\.

 

 9: c:\fortest\dir6\.

 

 10: c:\fortest\dir7\.

 

 11: c:\fortest\dir8\.

 

 12: c:\fortest\dir9\.

 

カレントディレクトリ(.)にだけマッチさせるような感じですね。

ファイルの中身へのアクセス

さて、次はいよいよファイルの中身へのアクセスです。これは/Fオプションで実現できます。

まず、テストのためにファイル内に10行書かれているファイルを用意します。これもfor文でやりましょう。

 1: c:\fortest>for /L %i IN (1,1,10) DO echo %i行目 >> sample.txt

 

 2:

 

 3: c:\fortest>echo 1行目  1>>sample.txt

 

 4:

 

 5: c:\fortest>echo 2行目  1>>sample.txt

 

 6:

 

 7: c:\fortest>echo 3行目  1>>sample.txt

 

 8:

 

 9: c:\fortest>echo 4行目  1>>sample.txt

 

 10:

 

 11: c:\fortest>echo 5行目  1>>sample.txt

 

 12:

 

 13: c:\fortest>echo 6行目  1>>sample.txt

 

 14:

 

 15: c:\fortest>echo 7行目  1>>sample.txt

 

 16:

 

 17: c:\fortest>echo 8行目  1>>sample.txt

 

 18:

 

 19: c:\fortest>echo 9行目  1>>sample.txt

 

 20:

 

 21: c:\fortest>echo 10行目  1>>sample.txt

 

 22:

 

 23: c:\fortest>type sample.txt

 

 24: 1行目

 

 25: 2行目

 

 26: 3行目

 

 27: 4行目

 

 28: 5行目

 

 29: 6行目

 

 30: 7行目

 

 31: 8行目

 

 32: 9行目

 

 33: 10行目

 

このファイルの中身を1行づつ読み取ってみます。

 1: c:\fortest>for /F %i IN (sample.txt) DO @echo %i

 

 2: 1行目

 

 3: 2行目

 

 4: 3行目

 

 5: 4行目

 

 6: 5行目

 

 7: 6行目

 

 8: 7行目

 

 9: 8行目

 

 10: 9行目

 

 11: 10行目

 

「type sample.txt」を実行した結果と同じ結果になるわけですが、1行づつ読み取り、それが変数%iに入れられ、それが1行づつechoされているのがわかりますでしょうか。

もうちょっとわかりやすくするために以下のようにしてみましょうか。

 1: c:\fortest>for /F %i IN (sample.txt) DO @echo %iを出力しています。

 

 2: 1行目を出力しています。

 

 3: 2行目を出力しています。

 

 4: 3行目を出力しています。

 

 5: 4行目を出力しています。

 

 6: 5行目を出力しています。

 

 7: 6行目を出力しています。

 

 8: 7行目を出力しています。

 

 9: 8行目を出力しています。

 

 10: 9行目を出力しています。

 

 11: 10行目を出力しています。

 

あまり内容は変わっていませんが、変数の中にファイルの内容が1行づつ入っていく様子がわかるかと思います。

ちなみに/Fオプションを使っているときにはパターンマッチは行えません。つまり内容を読み込んで処理できるのは1ファイルだということです。

 1: c:\fortest>for /F %i IN (*.txt) DO @echo %iを出力しています。

 

 2: ファイル *.txt が見つかりません。

 

文字列の処理、コマンドの結果

上記の/Fオプションはファイルの中身に対してだけではなくて、文字列に対してやコマンドの結果に対しても同じように処理できます。

 1: c:\fortest>for /F %i IN ("hogehoge") DO @echo %i

 

 2: hogehoge

 

これだとただ単にechoしているのと変わらないのですが(どう嬉しいのかはもうちょっと待ってください)。文字列は変数に入れておくこともできます。

 1: c:\fortest>set mojiretsu=hogehoge

 

 2:

 

 3: c:\fortest>echo %mojiretsu%

 

 4: hogehoge

 

 5:

 

 6: c:\fortest>for /F %i IN ("%mojiretsu%") DO @echo %i

 

 7: hogehoge

 

コマンドの結果を処理する場合には「’’」を使ってコマンドを囲むことで実現できます。

 1: c:\fortest>for /F %i IN ('ipconfig') DO @echo %i

 

 2: Windows

 

 3: Wireless

 

 4: 接続固有の

 

 5: リンクローカル

 

 6: IPv4

 

 7: サブネット

 

 8: デフォルト

 

 9: イーサネット

 

 10: メディアの状態.

 

 11: 接続固有の

 

 12: Tunnel

 

 13: メディアの状態.

 

 14: 接続固有の

 

 15: Tunnel

 

 16: メディアの状態.

 

 17: 接続固有の

 

 18: Tunnel

 

 19: 接続固有の

 

 20: IPv6

 

 21: リンクローカル

 

 22: デフォルト

 

 23: Tunnel

 

 24: メディアの状態.

 

 25: 接続固有の

 

 26: Tunnel

 

 27: メディアの状態.

 

 28: 接続固有の

 

おや。出力がipconfigの結果そのままではありませんね。これは規定の状態で以下のようになっているからです。(ヘルプより引用)

既定では、/F は、各ファイルの各行から、空白で区切られた最初のトークンを取得して渡します。空白行はスキップされます。

空白行はスキップされた上で、空白で区切っているわけです。もう一度単純な文字列を処理する例を見ましょう。

 1: c:\fortest>for /F %i IN ("hoge1 hoge2") DO @echo %i

 

 2: hoge1

 

文字列は空白で区切られているので1つめのトークンの”hoge1”が%iに入れられています。2つめのトークンである”hoge2”は単純に捨てられています。これも受け取りたい場合にはtokensオプションを指定します。

 1: c:\fortest>for /F "tokens=*" %i IN ("hoge1 hoge2") DO @echo %i

 

 2: hoge1 hoge2

 

 

 1: c:\fortest>for /F "tokens=*" %i IN ('ipconfig') DO @echo %i

 

 2: Windows IP 構成

 

 3: Wireless LAN adapter wlan:

 

 4: 接続固有の DNS サフィックス . . . :

 

 5: リンクローカル IPv6 アドレス. . . . : fe80::8d7e:8925:9d7e:38a2%18

 

 6: IPv4 アドレス . . . . . . . . . . : 192.168.1.108

 

 7: サブネット マスク . . . . . . . . : 255.255.255.0

 

 8: デフォルト ゲートウェイ . . . . . : 192.168.1.1

 

 9: イーサネット アダプター lan:

 

 10: メディアの状態. . . . . . . . . . : メディアは接続されていません

 

 11: 接続固有の DNS サフィックス . . . : test.local

 

 12: Tunnel adapter isatap.jbs.local:

 

 13: メディアの状態. . . . . . . . . . : メディアは接続されていません

 

 14: 接続固有の DNS サフィックス . . . :

 

 15: Tunnel adapter 6TO4 Adapter:

 

 16: メディアの状態. . . . . . . . . . : メディアは接続されていません

 

 17: 接続固有の DNS サフィックス . . . :

 

 18: Tunnel adapter ローカル エリア接続* 14:

 

 19: 接続固有の DNS サフィックス . . . :

 

 20: IPv6 アドレス . . . . . . . . . . . : 2001:0:4137:9e76:1cca:16f7:2518:641c

 

 21: リンクローカル IPv6 アドレス. . . . : fe80::1cca:16f7:2518:641c%15

 

 22: デフォルト ゲートウェイ . . . . . : ::

 

 23: Tunnel adapter isatap.{0A10F0FC-9ABB-42D0-8C73-C71B2976D3B0}:

 

 24: メディアの状態. . . . . . . . . . : メディアは接続されていません

 

 25: 接続固有の DNS サフィックス . . . :

 

 26: Tunnel adapter Reusable Microsoft 6To4 Adapter:

 

 27: メディアの状態. . . . . . . . . . : メディアは接続されていません

 

 28: 接続固有の DNS サフィックス . . . :

 

上記の2つの例では「tokens=*」とオプションを指定することで空白で区切ることをせず、行全部を1つのトークンにするように指定しました。なので、1行全てが%iに入っています。

空白では区切りつつ、2つの別々の変数で受け取る場合には以下の用にします。

 1: c:\fortest>for /F "tokens=1,2" %i IN ("hoge1 hoge2") DO @echo %i %j

 

 2: hoge1 hoge2

 

「tokens=1,2」と指定することで1番目と2番目のトークンをそれぞれ%i, %jに入力しています。%iは明示的に宣言されているのですが、%jはいきなり登場しています。これはもうこういうものだと思ってしまうしか無いと思います。%iからはじめるなら、%i, %j, %k …と順番になります。

もちろんtokenの選び方は自由です。

 1: c:\fortest>for /F "tokens=1,3" %i IN ("hoge1 hoge2 hoge3") DO @echo %i %j

 

 2: hoge1 hoge3

 

 3:

 

上記のように1番目と3番目を取得するようなこともできます。

 1: c:\fortest>for /F "tokens=1,3*" %i IN ("hoge1 hoge2 hoge3 hoge4 hoge5 hoge6") DO @echo %i %j - %k

 

 2: hoge1 hoge3 - hoge4 hoge5 hoge6

 

上記のように*を使うとその後のすべての文字が次の変数(ここでは%k)に入ります。*の前には「,」は必要ありません。(ちょっと文法的に違和感がありますが・・・)

 1: c:\fortest>for /F "tokens=1-5" %i IN ("hoge1 hoge2 hoge3 hoge4 hoge5") DO @echo %i %j %k %l %m

 

 2: hoge1 hoge2 hoge3 hoge4 hoge5

 

 3:

 

 4: c:\fortest>for /F "tokens=1,2,3,4,5" %i IN ("hoge1 hoge2 hoge3 hoge4 hoge5") DO @echo %i %j %k %l %m

 

 5: hoge1 hoge2 hoge3 hoge4 hoge5

 

上記のように”token=1-5”のように範囲で書くこともできます。この場合”tokens=1,2,3,4,5”と記述したのと全く同じ意味になります。

次に区切り文字です。規定では空白ですが、delimsオプションで指定することができます。

 1: c:\fortest>for /F "tokens=1,2,3 delims=," %i IN ("hoge1,hoge2,hoge3") DO @echo %i %j %k %l %m

 

 2: hoge1 hoge2 hoge3 %l %m

 

これは,(カンマ)で区切った例です。これを使えばCSVファイルを扱えるわけです。

CSVファイルの読み込み

簡単なCSVファイルを準備します。

 1: c:\fortest>echo 1-1,1-2,1-3,1-4,1-5 > sample.txt

 

 2:

 

 3: c:\fortest>echo 2-1,2-2,2-3,2-4,2-5 >> sample.txt

 

 4:

 

 5: c:\fortest>echo 3-1,3-2,3-3,3-4,3-5 >> sample.txt

 

 6:

 

 7: c:\fortest>type sample.txt

 

 8: 1-1,1-2,1-3,1-4,1-5

 

 9: 2-1,2-2,2-3,2-4,2-5

 

 10: 3-1,3-2,3-3,3-4,3-5

 

このCSVを1行づつ読み込み、カンマで区切り、5つの変数にそれぞれ値を代入し、表示します。

 1: c:\fortest>for /F "tokens=1,2,3,4,5 delims=," %i IN (sample.txt) DO @echo %i %j %k %l %m

 

 2: 1-1 1-2 1-3 1-4 1-5

 

 3: 2-1 2-2 2-3 2-4 2-5

 

 4: 3-1 3-2 3-3 3-4 3-5

 

CSVファイルにコメント行があり読み飛ばしたい時にはeolオプションが使えます。

テスト用のCSVファイルを用意します。

 1: c:\fortest>echo #コメント行です。 >> sample.txt

 

 2:

 

 3: c:\fortest>echo 4-1,4-2,4-3,4-4,4-5 >> sample.txt

 

 4:

 

 5: c:\fortest>type sample.txt

 

 6: 1-1,1-2,1-3,1-4,1-5

 

 7: 2-1,2-2,2-3,2-4,2-5

 

 8: 3-1,3-2,3-3,3-4,3-5

 

 9: #コメント行です。

 

 10: 4-1,4-2,4-3,4-4,4-5

 

 1: c:\fortest>for /F "tokens=1,2,3,4,5 delims=, eol=#" %i IN (sample.txt) DO @echo %i %j %k %l %m

 

 2: 1-1 1-2 1-3 1-4 1-5

 

 3: 2-1 2-2 2-3 2-4 2-5

 

 4: 3-1 3-2 3-3 3-4 3-5

 

 5: 4-1 4-2 4-3 4-4 4-5

 

「eol=#」というオプションを追加することでコメント行をスキップすることが出来ました。

ファイル名に空白を含むファイルを扱いたい時

ここまでの知識でかなりの事が出来るのですが、このままだと「ファイル名に空白を含むものの処理」がうまくできなくて困ってしまいます。ちょっとやろうとしてみましょう。

 1: c:\fortest>echo hoge > "sample file.txt"

 

 2:

 

 3: c:\fortest>dir

 

 4:  ドライブ C のボリューム ラベルがありません。

 

 5:  ボリューム シリアル番号は C0AF-1B4F です

 

 6:

 

 7:  c:\fortest のディレクトリ

 

 8:

 

 9: 2012/03/16  00:00    <DIR>          .

 

 10: 2012/03/16  00:00    <DIR>          ..

 

 11: 2012/03/15  22:05    <DIR>          dir1

 

 12: 2012/03/15  22:05    <DIR>          dir10

 

 13: 2012/03/15  22:05    <DIR>          dir2

 

 14: 2012/03/15  22:05    <DIR>          dir3

 

 15: 2012/03/15  22:05    <DIR>          dir4

 

 16: 2012/03/15  22:05    <DIR>          dir5

 

 17: 2012/03/15  22:05    <DIR>          dir6

 

 18: 2012/03/15  22:05    <DIR>          dir7

 

 19: 2012/03/15  22:05    <DIR>          dir8

 

 20: 2012/03/15  22:05    <DIR>          dir9

 

 21: 2012/03/16  00:00                 7 sample file.txt

 

 22: 2012/03/15  23:51               107 sample.txt

 

 23: 2012/03/15  21:55                10 sample1.txt

 

 24: 2012/03/15  21:55                11 sample10.txt

 

 25: 2012/03/15  21:55                10 sample2.txt

 

 26: 2012/03/15  21:55                10 sample3.txt

 

 27: 2012/03/15  21:55                10 sample4.txt

 

 28: 2012/03/15  21:55                10 sample5.txt

 

 29: 2012/03/15  21:55                10 sample6.txt

 

 30: 2012/03/15  21:55                10 sample7.txt

 

 31: 2012/03/15  21:55                10 sample8.txt

 

 32: 2012/03/15  21:55                10 sample9.txt

 

 33:               12 個のファイル                 215 バイト

 

 34:               12 個のディレクトリ  142,817,693,696 バイトの空き領域

 

 1: c:\fortest>for /F %i IN (sample file.txt) DO @echo %i

 

 2: ファイル sample が見つかりません。

 

 3:

 

 4: c:\fortest>for /F %i IN ("sample file.txt") DO @echo %i

 

 5: sample

 

 6:

 

 7: c:\fortest>for /F %i IN ('sample file.txt') DO @echo %i

 

 8: 'sample' は、内部コマンドまたは外部コマンド、

 

 9: 操作可能なプログラムまたはバッチ ファイルとして認識されていません。

 

うーん。うまくいきません。こういう時のためにusebackqオプションがあります。このオプションを有効にすると”(ダブルクォート), ‘(シングルクォート), `(バッククォート)の扱いが変わります。

 1: c:\fortest>for /F "usebackq" %i IN ("sample file.txt") DO @echo %i

 

 2: hoge

 

 1: c:\fortest>for /F "usebackq" %i IN ('ipconfig') DO @echo %i

 

 2: ipconfig

 

 3:

 

 4: c:\fortest>for /F "usebackq" %i IN (`ipconfig`) DO @echo %i

 

 5: Windows

 

 6: Wireless

 

 7: 接続固有の

 

 8: リンクローカル

 

 9: IPv4

 

 10: サブネット

 

 11: デフォルト

 

 12: イーサネット

 

 13: メディアの状態.

 

 14: 接続固有の

 

 15: Tunnel

 

 16: メディアの状態.

 

 17: 接続固有の

 

 18: Tunnel

 

 19: メディアの状態.

 

 20: 接続固有の

 

 21: Tunnel

 

 22: 接続固有の

 

 23: IPv6

 

 24: リンクローカル

 

 25: デフォルト

 

 26: Tunnel

 

 27: メディアの状態.

 

 28: 接続固有の

 

 29: Tunnel

 

 30: メディアの状態.

 

 31: 接続固有の

 

このように、usebackqオプションを有効にすると、ダブルクォートは文字列ではなくてファイル名として扱われます。シングルクオートはコマンドではなく文字列になり、バッククォートがコマンドになります。

置換

変数を置換出来る機能も見ておきましょう。置換というか表現の変更といった方が近いかもしれません。

 1: c:\fortest>for /F %i IN (""test"") DO @echo %i

 

 2: "test"

 

 3:

 

 4: c:\fortest>for /F %i IN (""test"") DO @echo %~i

 

 5: test

 

変数名の前に~をつけると引用句(“)が削除されます。

 1: c:\fortest>for %i IN (*.txt) DO @echo %i

 

 2: sample file.txt

 

 3: sample.txt

 

 4: sample1.txt

 

 5: sample10.txt

 

 6: sample2.txt

 

 7: sample3.txt

 

 8: sample4.txt

 

 9: sample5.txt

 

 10: sample6.txt

 

 11: sample7.txt

 

 12: sample8.txt

 

 13: sample9.txt

 

 14:

 

 15: c:\fortest>for %i IN (*.txt) DO @echo %~fi

 

 16: c:\fortest\sample file.txt

 

 17: c:\fortest\sample.txt

 

 18: c:\fortest\sample1.txt

 

 19: c:\fortest\sample10.txt

 

 20: c:\fortest\sample2.txt

 

 21: c:\fortest\sample3.txt

 

 22: c:\fortest\sample4.txt

 

 23: c:\fortest\sample5.txt

 

 24: c:\fortest\sample6.txt

 

 25: c:\fortest\sample7.txt

 

 26: c:\fortest\sample8.txt

 

 27: c:\fortest\sample9.txt

 

変数名の前に~fをつけると絶対パスで表示します。

 1: c:\fortest>for %i IN (*.txt) DO @echo %~di

 

 2: c:

 

 3: c:

 

 4: c:

 

 5: c:

 

 6: c:

 

 7: c:

 

 8: c:

 

 9: c:

 

 10: c:

 

 11: c:

 

 12: c:

 

 13: c:

 

変数名の前に~dをつけるとドライブ名のみ表示します。

 1: c:\fortest>for %i IN (*.txt) DO @echo %~pi

 

 2: \fortest\

 

 3: \fortest\

 

 4: \fortest\

 

 5: \fortest\

 

 6: \fortest\

 

 7: \fortest\

 

 8: \fortest\

 

 9: \fortest\

 

 10: \fortest\

 

 11: \fortest\

 

 12: \fortest\

 

 13: \fortest\

 

変数名の前に~pをつけるとパス名のみ表示します。

 1: c:\fortest>for %i IN (*.txt) DO @echo %~ni

 

 2: sample file

 

 3: sample

 

 4: sample1

 

 5: sample10

 

 6: sample2

 

 7: sample3

 

 8: sample4

 

 9: sample5

 

 10: sample6

 

 11: sample7

 

 12: sample8

 

 13: sample9

 

変数名の前に~nをつけるとファイル名のみ表示します。

 1: c:\fortest>for %i IN (*.txt) DO @echo %~xi

 

 2: .txt

 

 3: .txt

 

 4: .txt

 

 5: .txt

 

 6: .txt

 

 7: .txt

 

 8: .txt

 

 9: .txt

 

 10: .txt

 

 11: .txt

 

 12: .txt

 

 13: .txt

 

変数名の前に~xをつけると拡張子のみ表示します。

 1: c:\fortest>for %i IN (*.txt) DO @echo %~si

 

 2: c:\fortest\SAMPLE~1.TXT

 

 3: c:\fortest\sample.txt

 

 4: c:\fortest\sample1.txt

 

 5: c:\fortest\sample10.txt

 

 6: c:\fortest\sample2.txt

 

 7: c:\fortest\sample3.txt

 

 8: c:\fortest\sample4.txt

 

 9: c:\fortest\sample5.txt

 

 10: c:\fortest\sample6.txt

 

 11: c:\fortest\sample7.txt

 

 12: c:\fortest\sample8.txt

 

 13: c:\fortest\sample9.txt

 

変数名の前に~sをつけると短い名前を表示します。

 1: c:\fortest>for %i IN (*.txt) DO @echo %~ai

 

 2: --a------

 

 3: --a------

 

 4: --a------

 

 5: --a------

 

 6: --a------

 

 7: --a------

 

 8: --a------

 

 9: --a------

 

 10: --a------

 

 11: --a------

 

 12: --a------

 

 13: --a------

 

変数名の前に~aをつけるとファイルの属性を表示します。

 1: c:\fortest>for %i IN (*.txt) DO @echo %~ti

 

 2: 2012/03/16 00:00

 

 3: 2012/03/15 23:51

 

 4: 2012/03/15 21:55

 

 5: 2012/03/15 21:55

 

 6: 2012/03/15 21:55

 

 7: 2012/03/15 21:55

 

 8: 2012/03/15 21:55

 

 9: 2012/03/15 21:55

 

 10: 2012/03/15 21:55

 

 11: 2012/03/15 21:55

 

 12: 2012/03/15 21:55

 

 13: 2012/03/15 21:55

 

変数名の前に~tをつけると日付/時刻を表示します。

 1: c:\fortest>for %i IN (*.txt) DO @echo %~zi

 

 2: 7

 

 3: 107

 

 4: 10

 

 5: 11

 

 6: 10

 

 7: 10

 

 8: 10

 

 9: 10

 

 10: 10

 

 11: 10

 

 12: 10

 

 13: 10

 

変数名の前に~zをつけるとファイルのサイズを表示します。

 1: c:\fortest>for %i IN (*.txt) DO echo %~$PATH:i

 

 2:

 

 3: c:\fortest>echo

 

 4: ECHO は <ON> です。

 

 1: c:\fortest>set Path=%Path%;c:\fortest

 

 2:

 

 3: c:\fortest>for %i IN (*.txt) DO echo %~$PATH:i

 

 4:

 

 5: c:\fortest>echo c:\fortest\sample file.txt

 

 6: c:\fortest\sample file.txt

 

上記の例はかなりわかりにくいですが、環境変数PATHの中に記述されているディレクトリを探し、そこに検索結果のファイルやディレクトリが合致すれば表示される、そうでなければ空になる、という動きをします。PATHに含まれているファイル、ディレクトリなのかどうかの判定に使えると思います。

バッチファイルに記述する場合の注意

ここまでforを見てきましたが全て「コマンドプロンプト上で実行する際の記述」であることに注意してください。ヘルプにも以下の記載があります。

バッチ プログラムで FOR コマンドを使用するときは、%変数の代わりに、%%変数を使用してください。

コマンドプロンプトで動いたものをそのままバッチファイルに貼りつけてはいけない」ということです。

具体的には以下の例であれば

 1: c:\fortest>for %i IN (*.txt) DO @echo %i

 

 2: sample file.txt

 

 3: sample.txt

 

 4: sample1.txt

 

 5: sample10.txt

 

 6: sample2.txt

 

 7: sample3.txt

 

 8: sample4.txt

 

 9: sample5.txt

 

 10: sample6.txt

 

 11: sample7.txt

 

 12: sample8.txt

 

 13: sample9.txt

 

バッチファイルには以下の用に記述する必要があります。

 1: for %%i IN (*.txt) DO @echo %%i

 

注意して下さい。

 

forの可能性

さて、ここまでforコマンドでできることを見てきました。「かなりの事ができる」ということがお分かりいただけたかと思います。「もういやだ」という人も多いかとは思いますが…。でも、バッチファイルを作るしか無いのであれば仕方が無いです……。

随分このエントリも長くなってしまいました。forを駆使した使える実例に関してはまた別のエントリで紹介したいと思います。

Microsoft MVP for Microsoft Azure。「Windowインフラ管理者入門」著者。Windows系中心のインフラよりの何でも屋。エレキベースを演奏します。将棋も少しやります。ハイブリッドクラウド研究会(HCCJP)主催。最近はYouTuberです http://bit.ly/2NTCKmj

3件のコメント

  1. この場合はどうしたらいいんですかね…

    “C:\Program Files (x86)\TEST\testproj.exe -t -v “D:\TEST\dat.txt” -u user -p pass -e “hoge@test.com” | FIND “huga”

  2. さとっちさん。コメントありがとうございます。仰るとおりです。コマンドに間違いがありました。申し訳ないです。

    そもそも、Wordpressの仕様との兼ね合いで「\」が全部消えてしまっていることに気が付きました。全体的に対処が必要なので対応しようと思います。

    ありがとうございました。

  3. 手元環境(Windows 7 Enterprise 64bit)では「再帰処理」の段落のコマンド、

    for /L %i IN (1,1,10) DO echo sample%i > .dir%isample%i.txt

    は、

    for /L %i IN (1,1,10) DO echo sample%i > .\dir%i\sample%i.txt

    としないと、フォルダは以下へのファイルは出来ませんでした。

コメントを残す

メールアドレスが公開されることはありません。

x
いつもブログをご覧いただきありがとうございます!最近はブログよりもYoutubeに力を入れていますので是非Youtubeもご覧ください!
胡田昌彦のコンピューター系チャンネル