質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Windows 7

Microsoft Windows 7は過去にリリースされたMicrosoft WindowsのOSであり、Windows8の1代前です。2009年の7月にリリースされ販売されました。Windows7の前はWindowsVistaで、その更に3年前にリリースされました。

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

Q&A

解決済

1回答

10321閲覧

あバッチ処理で二重のfor文を実装したい

harrier

総合スコア14

Windows 7

Microsoft Windows 7は過去にリリースされたMicrosoft WindowsのOSであり、Windows8の1代前です。2009年の7月にリリースされ販売されました。Windows7の前はWindowsVistaで、その更に3年前にリリースされました。

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

0グッド

0クリップ

投稿2017/11/21 01:21

編集2017/11/21 03:26

バッチ処理にて2重のfor文を使用したコードの実装を行いたいと考えています。
コードの概要は以下の通りです

setlocal enabledelaydexpansion for /L %%N in (1,1,50) do ( 対象のフォルダ50個それぞれにあるファイル数cをそれぞれ取得 for /L %%i in (0,1,%c%) do ( 前のfor文で指されているフォルダ内のファイル(すべて0からの番号で記載されている)の全てに対して処理を行うコード ) )

以上の形でプログラムを組んでおります。
ここで、for文の中のfor文で”フォルダ内のファイル全てに処理を行うコード”がi=0のときしか行われず、for文のループを抜け出し、一つ目のfor文の方の作業に戻ってしまい、結果として、対象としたフォルダ内のファイル数をカウントするところまでは出来るのですが、その次のfor文が1度しか回らないという事態になっております。

インターネットで検索を行っても具体的な解決策が見当たらないため、相談させていただきました。解決策をご存知の方いらっしゃいましたらご回答のほどお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

それはWindowsのバッチ処理特有の問題によるものですね。知らないとはまります。バッチ処理では、環境変数の展開が「行または()ブロックを読み取ったときに1回だけ」行われます。ご質問のようにforブロック内で環境変数を設定しても、それを展開する際は「読み取ったときに設定されていた内容」に置き換わります。

例えば、こんな感じのバッチファイルを作ったとして、実行してみれば明らかに意図通りではないことが判ると思います。

dos

1@echo off 2 3set HOGE=123 4echo A:%HOGE% 5 6set HOGE=456 & echo B:%HOGE% 7 8( 9 set HOGE=789 10 echo C:%HOGE% 11) 12 13for %%A in (100 200 300) do ( 14 set HOGE=%%A 15 echo D:%HOGE% 16)

一応回避策は用意されていて、読み取り時ではなく「コマンド実行時」に環境変数を展開する「遅延環境変数」という仕組みがあります。SETLOCAL ENABLEDELAYEDEXPANSION(大文字小文字不問)というコマンドを実行すると遅延環境変数が有効になります。通常はバッチファイルの先頭付近に書きます。そして、環境変数の展開には%ではなく!で囲みます。

上記バッチはこんな感じで書き換えます。これだと意図通りに実行されることが確認できると思います。

dos

1@echo off 2setlocal enabledelayedexpansion 3 4set HOGE=123 5echo A:!HOGE! 6 7set HOGE=456 & echo B:!HOGE! 8 9( 10 set HOGE=789 11 echo C:!HOGE! 12) 13 14for %%A in (100 200 300) do ( 15 set HOGE=%%A 16 echo D:!HOGE! 17)

投稿2017/11/21 03:02

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

harrier

2017/11/21 03:25

コメントありがとうございます。 プログラムの方へ記し忘れたのですが、setlocal nabledelaydexpansionコードはすでに導入しています。 ほかに考えられる間違いとして括弧のつける場合などを検討してみましたが特に間違いは見当たりませんでした。
harrier

2017/11/21 03:33

試しに @echo off setlocal enabledelayedexpansion for /L %%N in (1,1,50) do ( echo ああああああああああああ for /L %%i in (0,1,30) do ( echo !i! ) ) 以上のようなプログラムでまわるか実行をしてみたのですが、echo!i!の部分で ECHOは<OFF>です。 と出力がされてしまっているため、enabledelayedexpansionがうまく適用されていない可能性があるのですが、どこかに間違いはありますでしょうか?
catsforepaw

2017/11/21 03:51

forの変数%%iは環境変数ではないのでそのまま%%iとしてください。
catsforepaw

2017/11/21 04:01

それと、setlocal enabledelaydexpansionをやっても、%c%のままだと遅延環境変数にはなりません。
harrier

2017/11/21 04:05 編集

コメントありがとうございます %%iとしたことで、試しに行ったプログラムは回りました 本題のプログラムへ戻りまして、for文の中for文に対してechoをかけて繰り返し処理が行われているのか確認を行ったところ、出力される値は0でとまっており相変わらず動作がされない状態です。 最初に定義した方のfor文はしっかりと回っています
harrier

2017/11/21 04:11

また、2個目のfor文では1つ目のfor文で取得した値cを使用していますが、2つ目のfor文でcとした部分を適当な定数()とした場合はきちんと2つ目のfor文も回りましたので、値の受け渡しがうまくいっていないのでしょうか?
catsforepaw

2017/11/21 04:12

バッチ処理の内容がわからないので判断のしようがありません。問題が再現できるバッチを提示していただけないでしょうか。
catsforepaw

2017/11/21 04:18

「%c%」を「!c!」に直しましたか?
harrier

2017/11/21 05:16

コメントありがとうございます 受け渡し時の「%c%」を「!c!」へと変更したことでうまく動きました ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問