[前の記事]« テキストファイル各行の末尾のスペースのみ削除する方法
[次の記事]文字列の指定位置から指定の長さを読み取るには »

関連オンラインソフト配布サイト:
Vector>ダウンロード(top) |>MS-DOSまたは汎用 | >WindowsVista/XP/2000/NT

▲カテゴリー「FOR /F」索引へ
▲カテゴリー「遅延環境変数の展開」索引へ

forでのファイル読み込み処理がうまく動かない

1563.
forでファイルから読み込んだ内容を処理する
2007年01月04日(木) 02時25分
elz
初めて発言します。
あまり詳しくないのですが、御教授お願いします。

環境:Windows2003
forにてリストファイルから1行ずつ読み込み、読み込んだ1行に記述されたファイルを順次シフトさせる処理を行いたいのですが、なぜか繰り返し処理とならず、for内でファイルの存在確認をしたところで抜けてしまいます。(ファイルが存在するのにもかかわらず)
サブルーチンを使用せずに実行させたいのです。
力不足なので見よう見まねで作っているので、基礎知識があまりありませんが、教えてください。

file.lst内容:
D:\test1\aaa.log
D:\test1\bbb.log
D:\test2\ccc.log

for /F "tokens=1" %%i in (D:\tmp\file.lst) do (
set TARGET_LOG=%%i
set SHIFTCYCLE=3
if not exist %TARGET_LOG% ( goto ERR1 )

:OLD_LOG
if %SHIFTCYCLE% EQU 1 ( goto MAKE_NEW )
set /A COUNT=%SHIFTCYCLE% -1
if exist %TARGET_LOG%.%COUNT% move /y %TARGET_LOG%.%COUNT% %TARGET_LOG%.%SHIFTCYCLE%
if not %ERRORLEVEL% == 0 ( goto ERR2 )
set /A SHIFTCYCLE=%SHIFTCYCLE% -1
goto OLD_LOG

:MAKE_NEW
if exist %TARGET_LOG% copy /y /v %TARGET_LOG% %TARGET_LOG%.%SHIFTCYCLE%
if not %ERRORLEVEL% == 0 ( goto ERR3 )

)
set end_code=0
1565.
Re:forでファイルから読み込んだ内容を処理する
2007年01月04日(木) 19時55分
YanaKen◆c0rnJ1Q=
>for /F "tokens=1" %%i in (D:\tmp\file.lst) do (
>set TARGET_LOG=%%i
>set SHIFTCYCLE=3
>if not exist %TARGET_LOG% ( goto ERR1 )

 forループ内の処理を( )でくくって複数行とし、その中でsetコマンドを実行されていますね。
 この場合は「遅延環境変数の展開」について理解・把握されることが先決だと思います。

http://fpcu.on.coocan.jp/dosvcmd/bbs/log/cat3/set_path/cat51/

YanaKen

1566.
Re:forでファイルから読み込んだ内容を処理する
2007年01月04日(木) 22時08分
elz
遅延環境変数の展開」ですか。昨夜からいろいろ見て回っていたのですが。
これという使い方がいまだにわからないのです。for文内でsetしている箇所に!SHIFTCYCLE!のようにしてみると、延々回り続けてしまいました。 
組み合わせ方も理解不足です。 
forでのループ処理は一般的ではないのでしょうか。 
それとも実現するには複雑になってしまうためあまり使わないのでしょうか。 
UNIXであればシェルで行数を数えて、カウントアップさせながら処理が可能です。
これまでバッチに触れる機会がなかったのですが、やっとここまでたどり着いたので、
何とか身に着けていこうと思います。 

現在は、下記のように変更して、%%iは値を取得することはできています。
ただし、for文の中でsetしているcount、SHIFTCYCLEの減算ができません。
初心者すぎて申し訳ないのですが、もう少し詳しく教えていただけないでしょうか。 

set SHIFTCYCLE=3 
setlocal 
for /F "tokens=1" %%i in (D:\tmp\file.lst) do ( 
if not exist %%i ( goto ERR1 ) 

:OLD_LOG 
if %SHIFTCYCLE% EQU 1 ( goto MAKE_NEW ) 
set /A COUNT=%SHIFTCYCLE% -1 
if exist %%i.%COUNT% move /y %%i.%COUNT% %%i.%SHIFTCYCLE% 
if not %ERRORLEVEL% == 0 ( goto ERR2 ) 
set /A SHIFTCYCLE=%SHIFTCYCLE% -1 
goto OLD_LOG_SHIFT 

:MAKE_NEW 
if exist %%i copy /y /v %%i %%i.%SHIFTCYCLE% 
if not %ERRORLEVEL% == 0 ( goto ERR3 ) 


endlocal 
set end_code=0

1572.
Re:forでファイルから読み込んだ内容を処理する
2007年01月05日(金) 12時28分
YanaKen◆c0rnJ1Q=
>遅延環境変数の展開」ですか。昨夜からいろいろ見て回っていたのですが。
>これという使い方がいまだにわからないのです。
 
SETLOCAL ENABLEDELAYEDEXPANSION
 は実行されていますか?
 書かれたサンプルでは前のほうにsetlocalと書かれた行がありますが、上記の通りのおまじないを書いておかないと「遅延環境変数の展開」の機能はオンにならないです。
 http://fpcu.on.coocan.jp/dosvcmd/bbs/log/cat3/set_path/cat51/3-0092.html

 ……で、実はもう1点、前回、とりあえず目についたのが「FOR ()内で 環境変数をセットして参照している」という部分であったためそのへんに絞ってコメントしてしまったのですが、お書きになったサンプルにはもう1つ「大きな問題点」があります。

>goto OLD_LOG_SHIFT 
 この飛び先はforの外でしょうか。それとも、少し前にある「:OLD_LOG 」というラベルの部分が実は書き間違いでここが本来のとび先、ということでしょうか。
 たぶん後者だと思うのですが、じつはfor ..in ..do ( ) の"( )"内ではループ外に飛び出すgotoだけが有効で、( )内のラベルに飛ばそうとするとエラーになります。
http://fpcu.on.coocan.jp/dosvcmd/bbs/log/cat3/for_in_do/4-1324.html
 したがって、gotoを用いた現在の処理は、1つバグが直るとそこでまた新たな問題をしょいこむことになると思います。

>forでのループ処理は一般的ではないのでしょうか。 
 いま書いたとおりFORループ内での処理中はGOTOが(ループ脱出以外には)使えないため、実際上、内側でのGOTOが必須なタイプのループ処理をサブルーチン化せずにfor内にまとめるのはむずかしいと思います。
 最初の発言に「サブルーチンを使用せずに実行させたいのです。」とお書きですけど、その前提を捨て、「サブルーチン化してcall」で考えるぶんには、 一連の処理を( )でくくらない限り「遅延環境変数」関連の問題は発生しないし、かえってシンプルに書ける可能性も高いのでは。

YanaKen
1575.
Re:forでファイルから読み込んだ内容を処理する
2007年01月05日(金) 14時25分
otn
> たぶん後者だと思うのですが、じつはfor ..in ..do ( ) の"( )"内ではループ外に飛び出すgotoだけが有効で、( )内のラベルに飛ばそうとするとエラーになります。
>http://fpcu.on.coocan.jp/dosvcmd/bbs/log/cat3/for_in_do/4-1324.html

goto自体はエラーにはなりません。ただし、gotoした途端に「for文の途中だった」ことを忘れてしまうようで、次の繰り返しに進みません。
従って、gotoが必要なケースではやはりサブルーチンにする必要があります。

上記URLで「エラーになる」と書かれているのは、ラベルのあとに文が無いからです。ラベルは文につけるものなのでラベル行の後に文が無いとエラーになります。書くことがなければ rem文でも書いておきます。
1578.
ありがとうございます
2007年01月05日(金) 19時32分
elz
YanaKenさん、otnさん、詳しい説明ありがとうございました。
>SETLOCAL ENABLEDELAYEDEXPANSION
> は実行されていますか?
> 書かれたサンプルでは前のほうにsetlocalと書かれた>行がありますが、上記の通りのおまじないを書いておか>ないと「遅延環境変数の展開」の機能はオンにならない>です。
おまじない。。。組み合わせ方が理解できませんでした。何を選択してもsetlocal以前の環境変数は持ってこられないという記述↓が購入した本に記載されてました。
「setlocalコマンドを実行する前の環境には無関係」

> 最初の発言に「サブルーチンを使用せずに実行させた>いのです。」とお書きですけど、その前提を捨て、「サ>ブルーチン化してcall」で考えるぶんには、一連の処理>を( )でくくらない限り「遅延環境変数」関連の問題は
>発生しないし、かえってシンプルに書ける可能性も高い>のでは。
サブルーチンを使わずにできると思い込んでいました。

>goto自体はエラーにはなりません。ただし、gotoした途>端に「for文の途中だった」ことを忘れてしまうようで、次の繰り返しに進みません。
>従って、gotoが必要なケースではやはりサブルーチンにする必要があります。

forやifの中での()には制限があるのですね。
gotoを使わないとなると、処理が変わってしまいます。
実は、サブルーチンに挑戦してみて、正常に稼動することが確認できました。
サブルーチンに対して抵抗感があったのですが、作ってみると簡単でした。なぜサブルーチンにしなくてはいけないのかが分かったので、それだけでも成長しました。
お二人とも丁寧な回答ありがとうございました。
 
 
 


カテゴリー「FOR /F」索引へ
カテゴリー「遅延環境変数の展開」索引へ

 

カテゴリー一覧

FPCU/FPCDIY QUICK LINK online
この上の各ジャンル名をクリックすると、下のウィンドウが切り替わります▼


=リンク集のインデックスはこちら=

資料書籍

About

2007年01月04日 22:50に投稿されたエントリーのページです。

ひとつ前の投稿は「テキストファイル各行の末尾のスペースのみ削除する方法」です。

次の投稿は「文字列の指定位置から指定の長さを読み取るには」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

This site is powered by Six Apart
Movable Type 3.33-ja
 
このブログについて | 運営:有限会社メディアポート