- ベストアンサー
バッチファイル 文字列操作のやり方
お世話になります。 バッチファイルのコマンドについてですが、 for文の中で 一番下の階層のファイル名の先頭5バイトが "abcde"のものだけ処理対象にしたいと考えています。 例えば、 C:\tempに以下のファイルがあったら C:\temp\abcdefg.txt ・・・(1) C:\temp\xxxxxxx.txt ・・・(2) C:\temp\abcde.txt ・・・(3) C:\temp\abc.txt ・・・(4) C:\temp\abcdezzzz.txt ・・・(5) (1)、(3)、(5)だけを処理させたいと考えています。 実装方法として、以下を考えましたがうまくいきません。 dir /s /b /a-d C\Temp > file.txt for /f "delims=" %%F in (file.txt) do ( set A=%%~nF% if "%%A:~0,5%"=="abcde" ( <処理コマンド> ) ) おそらくfor文の中で何個も命令を記述できないということと、 パラメータ修飾子の指定が間違っているからだと思われますが、 うまくできない理由を知りたいです。 よろしくお願いいたします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
簡単に書くと、 pushd C:\temp for /f %%F in ('dir /s /b /a-d abcde*') do <処理コマンド> もとの線で行くと、 dir /s /b /a-d C\Temp > file.txt for /f "delims=" %%F in (file.txt) do call :sub %%F goto :EOF :sub set A=%~n1 if "%A:~0,5%"=="abcde" ( <処理コマンド> (ファイル名は %1 で) ) goto :EOF
その他の回答 (4)
- deadline
- ベストアンサー率63% (1239/1943)
>・cmd /v:on は一回手作業で実行させれば効果が持続するのでしょうか? cmd /v:on で起動した『コマンドプロンプト』を終了するまでは、『遅延環境変数』の展開が行われます。一旦、『コマンドプロンプト』を終了し、再度、起動する際には、再び、cmd /v:on で起動しないと、『遅延環境変数』の展開は無効のままです。 『コマンドプロンプト』を起動する際、常に『遅延環境変数』の展開を有効にしたければ、下記のレジストリキーに"DelayedExpansion"という名前のD_WORD値を新規に作成し、0x00000001(16進表記)に設定します。"/v:on"オプション無しの cmd のみで『コマンドプロンプト』を起動しても『遅延環境変数』の展開が有効になります。 HKEY_CURRENT_USER\Software\Microsoft\Command Processor (←ユーザー個別の設定) "DelayedExpansion"=dword:00000001 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor (全ユーザー共通の設定) "DelayedExpansion"=dword:00000001 >・if "!A:~0,5!"=="abcde" ( にて、半角感嘆符"!"の中の変数Aには >%を付加しなくて良いのでしょうか? "%"は不要です。『遅延環境変数』の参照の際には、"%"の代わりに"!"を使います。 %A% ⇒ !A! %A:~0,5% ⇒ !A:~0,5! >・if文の後に echo !A! がありますが、確認のために行っているのでしょうか? はい、そうです。回答#4内のバッチをそのままメモ帳等にコピー&ペーストして保存後、実行してみてください。 該当するファイル名だけが表示されるはずです。
お礼
わかりました。丁寧なご回答ありがとうございます。 まだまだ勉強不足でした。ご指摘のヘルプなどをみて再チャレンジしてみたいと思います。
- deadline
- ベストアンサー率63% (1239/1943)
ご質問のように、"for"文内で変数を操作・参照する場合には、通常の"%A:~0,5%"では、"for"コマンドが実行される前の変数Aの値が参照され、望みどおりの結果が得られませんので、『遅延環境変数』の参照を使用します。 通常、『遅延環境変数』の展開はオフに設定されていますので、『コマンドプロンプト』を"/v:on"オプションを付けて、 cmd /v:on の書式で起動した上で、バッチファイルを実行する必要があります。 (『遅延環境変数』については、set /? でヘルプを参照すると、最後の方に記載されています。) 『遅延環境変数』の参照は、下記のバッチファイルの4行目、5行目のように半角感嘆符"!"を使用します。 @echo off for /f "delims=" %%F in ('dir /s /b /a-d C:\Temp') do ( set A=%%~nF if "!A:~0,5!"=="abcde" ( echo !A! ) ) なお、ご質問文中のバッチファイル内での変数の参照方法は間違っていますョ A=%%~nF% ⇒ A=%%~nf (最後の%が余分) %%A:~0,5% ⇒ %A:~0,5% (最初の%は1つです)
補足
ありがとうございました。遅延環境変数は全然知りませんでした。 ただ、バッチファイルを実行したらできませんでしたので 以下教えて頂けると有難いです。 ・cmd /v:on は一回手作業で実行させれば効果が持続するのでしょうか? ・if "!A:~0,5!"=="abcde" ( にて、半角感嘆符"!"の中の変数Aには %を付加しなくて良いのでしょうか? ・if文の後に echo !A! がありますが、確認のために行っているのでしょうか? 以下、実行できなかったソースになります。 rem 対象ファイルの一覧作成 dir /s /b /a-d C:\Temp > file.tmp for /f "delims=" %%F in (file.tmp) do ( set A=%%~nF if "!%A:~0,5!"=="abcde" ( echo !%A! for /f "delims=\ tokens=3" %%D in ("%%F") do ( for /f "delims=\ tokens=4" %%E in ("%%F") do ( <処理コマンド> ) ) ) )
ANo.2 です。ごめんなさい。 >でもこれだと"file.txt" を1個だけ引用して終わりそうなので、 >ここは変だと思いますけど。 は勘違いです。すみません。
> うまくできない理由を知りたいです。 どううまくできないのかを示してほしいですね。 また、表示を止めてないのだからどう展開されてるか表示を遡ってみれが どこが期待どおりでないか判断できるのでは? 確認してませんが、 > for /f "delims=" %%F in (file.txt) do ( は file.txt の内容からファイル名を1個ずつ引用したいのですか? でもこれだと"file.txt" を1個だけ引用して終わりそうなので、 ここは変だと思いますけど。
補足
言葉足らずでした。 うまくできないと申し上げたのは、 set A=%%~nF% if "%%A:~0,5%"=="abcde" ( の部分で "%%A:~0,5%"がどうやらファイル名の先頭5バイトを 認識していないようでした。 %%Aの%の数が多いのか、 そもそも for~doの中で 変数Aをsetセットしながら、if文を記述することが無理なのか という意味で、コーディングの誤りがあれば指摘して頂きたい ということで質問させてもらいました。
お礼
今回の私の質問ですが、notnotさんの pushd C:\temp for /f %%F in ('dir /s /b /a-d abcde*') do <処理コマンド> で簡単に処理できることがわかりました。 一番シンプルだったので使わせて頂きます。 どうもありがとうございました。