• ベストアンサー

バッチファイル 文字列操作のやり方

お世話になります。 バッチファイルのコマンドについてですが、 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文の中で何個も命令を記述できないということと、 パラメータ修飾子の指定が間違っているからだと思われますが、 うまくできない理由を知りたいです。 よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4845/10255)
回答No.1

簡単に書くと、 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

curryteam
質問者

お礼

今回の私の質問ですが、notnotさんの pushd C:\temp for /f %%F in ('dir /s /b /a-d abcde*') do <処理コマンド> で簡単に処理できることがわかりました。 一番シンプルだったので使わせて頂きます。 どうもありがとうございました。

その他の回答 (4)

  • deadline
  • ベストアンサー率63% (1239/1943)
回答No.5

>・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内のバッチをそのままメモ帳等にコピー&ペーストして保存後、実行してみてください。 該当するファイル名だけが表示されるはずです。

curryteam
質問者

お礼

わかりました。丁寧なご回答ありがとうございます。 まだまだ勉強不足でした。ご指摘のヘルプなどをみて再チャレンジしてみたいと思います。

  • deadline
  • ベストアンサー率63% (1239/1943)
回答No.4

ご質問のように、"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つです)

curryteam
質問者

補足

ありがとうございました。遅延環境変数は全然知りませんでした。 ただ、バッチファイルを実行したらできませんでしたので 以下教えて頂けると有難いです。 ・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 ( <処理コマンド> ) ) ) )

noname#103727
noname#103727
回答No.3

ANo.2 です。ごめんなさい。 >でもこれだと"file.txt" を1個だけ引用して終わりそうなので、 >ここは変だと思いますけど。 は勘違いです。すみません。

noname#103727
noname#103727
回答No.2

> うまくできない理由を知りたいです。 どううまくできないのかを示してほしいですね。 また、表示を止めてないのだからどう展開されてるか表示を遡ってみれが どこが期待どおりでないか判断できるのでは? 確認してませんが、 > for /f "delims=" %%F in (file.txt) do ( は file.txt の内容からファイル名を1個ずつ引用したいのですか? でもこれだと"file.txt" を1個だけ引用して終わりそうなので、 ここは変だと思いますけど。

curryteam
質問者

補足

言葉足らずでした。 うまくできないと申し上げたのは、 set A=%%~nF% if "%%A:~0,5%"=="abcde" ( の部分で "%%A:~0,5%"がどうやらファイル名の先頭5バイトを 認識していないようでした。 %%Aの%の数が多いのか、 そもそも for~doの中で 変数Aをsetセットしながら、if文を記述することが無理なのか という意味で、コーディングの誤りがあれば指摘して頂きたい ということで質問させてもらいました。

関連するQ&A

  • ファイルのバッチ処理について

    バッチ処理を勉強しているところです。 ひとつの問題が解決できていないので、わかるひとは教えて もらえませんか? C:\bom.txtがあって、C:\temp\a.txtとC:\temp\d.txt, C:\temp\a\a.txt と C:¥temp\b\e.txtもあります。 for でC:\bom.txtファイルとほかのファイルと再帰的に結合して、 ファイル名はそのままにしたいですが、 @set bomfilepath=C:\ 考えているバッチは以下のようになるが、失敗しました。 for /R %1 %%f in (*.*) do @( @rem echo %%f call copy /B %bomfilepath%bom.txt+%%f %%ftemp call del /Q %%f ren %%ftemp %%f ) 原因はどこですか?

  • バッチでファイルの読み込み

    Windowsバッチでファイルの読み込みをしようと思っているのですが、 下記コマンドの実行で「ファイルが見つかりません」となります。 ※パスにスペースを含むのでusebackqを使用しました。 FOR /F "usebackq tokens=1,2 delims= " %%i in ("c:\temp 1\data.txt") DO echo %%i WindowsServer2003でうまくいかなかったのですが、 Xpですれば問題なくファイルを読み込めました。 何か差があるのでしょうか?

  • バッチファイルで条件によって書き出さないようにしたい

    temp.txtというファイルのカンマ4つめが同じだったらテキストに出力しないバッチファイルを作りたいと思っています。 set sbuf=test for /f "tokens=4 delims=, " %%a in (C:temp.txt) do ( set saddress=%%a if %sbuf% == %%a ( ) else ( set saddress=%%a findstr %saddress% C:\sip_cmail\ping_sip.txt >> C:\out.txt ) set sbuf=%%a ) と書いてみたのですが、動きません。 流れとしては、一巡目に通ったときの値をbufにいれておいて、二順目通ったときに比べ、同じだったら何もしないで次に行く、としたいのですが、、 括弧が何十にもなると出来ないのでしょうか。 よろしくお願い致します。

  • バッチファイル 現在のフォルダ名をファイル名に置き換える

    こんにちは。超初心者なのですが教えてください。 ある複数フォルダに格納されている.txtファイルを、現在の フォルダ名を取得して、別フォルダにリネームして 格納するバッチファイルを作成したいと考えています。 for文を繰り返し使わなければいけないことはわかっているのですが、それをどう表現していいのか全然わかりません。 例えば、 データ取得元として以下のファイルがあったら C:\temp\20100101\data1.txt C:\temp\20100101\data2.txt C:\temp\20100101\data3.txt C:\temp\20100102\data1.txt C:\temp\20100102\data2.txt C:\temp\20100103\data1.txt C:\temp\20100103\data2.txt これを別フォルダに、現在のフォルダ名をファイル名にくっつけて 以下のように一つのフォルダに纏めて格納したいと思っています。 ファイルの中身はそのままコピーしたいので、どこかでcopyコマンド を使うかもしれないです。 C:\test\data1_20100101.txt C:\test\data2_20100101.txt C:\test\data3_20100101.txt C:\test\data1_20100102.txt C:\test\data2_20100102.txt C:\test\data1_20100103.txt C:\test\data2_20100103.txt 実装方法として以下までは考えましたが、これ以上は無理そうです。 rem set A=C:\temp rem set B=C:\test for %%A in (C:\temp\) do ( if not "%%A"=="" ( pushd "%%A" for /d %%B in (*) do ( if not "%%B"=="" ( pushd "%%B" for /d %%C in (*) do ( if not "%%C"=="" ( pushd "%%C" ) ) ) ) popd? ) ) 申し訳ありませんが、お助け願います。

  • バッチファイルで2行にわたるコマンドを入力したいのですが

    バッチファイルで複数行にわたるコマンドを打ちたいのですが、方法がわからなくて困っています。 for /f "tokens=1,2,3 delims=/ " %%a in ('date /t') do ( set hinichi=%%a%%b ) "C:\Program Files\Lhaca\Lhaca.exe" "test%hinichi%01.txt" "test%hinichi%02.txt" ・・・・・・・ と31個のファイルを圧縮するバッチです。 体裁の問題ですが、 for /f "tokens=1,2,3 delims=/ " %%a in ('date /t') do ( set hinichi=%%a%%b ) "C:\Program Files\Lhaca\Lhaca.exe" ? "test%hinichi%01.txt" ? "test%hinichi%02.txt" ・・・ としたいのですが各行のつなぎの記号?がわかりません。 ご存知の方、よろしくお願いいたします。

  • バッチファイル(for文)がうまく動かない

    以下のようなバッチファイルをWin2008上で実行しようとしています ------------------------------ @echo on set LOGFILE=C:\a.log set CONF=C:\a.txt FOR /F "tokens=1-3 delims=," %%i in (%CONF%) do ( echo %%i %%j %%k > %LOGFILE% 2>&1 ) ------------------------------ C:\a.txtの中身はこのようになっています ------------------------------ a,b,c e,f,g ------------------------------ 期待する結果は「1.」なのですが.batを実行しても「2.」の結果がログに表示されます どのように修正すれば期待の結果が得られますでしょうか ※ちなみに.batの実行ではなくコマンドプロンプトで[%%]を[%]に変更すれば正常に実行できました 1. ------------------------------ a b c e f g ------------------------------ 2. ------------------------------ e f g ------------------------------

  • Windows バッチを Linux へ移植したい

    FOR 文を使ってテキストファイルの中身を変数に格納するバッチファイルがあります。 FOR /F "tokens=1,2* delims==" %%i IN (test.txt) DO SET %%i=%%j [読み込む test.txt の内容] HOGE=A FUGA=B HAGE=C 実行すると、%HOGE% には A、%FUGA% には B、%HAGE% には C が代入されます。 これと同じ処理を Linux のシェルスクリプト(bash)で実現するにはどうすれば良いでしょうか。 while read ~ でやるのかなと思ったのですが、変数の処理がピンと来なくて困っています。 どうかご教授ください。

  • バッチファイル 2ファイルをfor /f処理したい

    バッチファイルで別の2つのファイルを読み込んでfor /f処理するには 変換前のファイルのファイル名と 変換後のファイルのファイル名が それぞれ別のファイルに書かれていて この2つのファイルを読み込んで リネームするバッチファイルを 記述したいのですが 2つのfor /fを使った場合、 一方が他方にネストされてしまうのですが このような場合は どのように記述するのでしょうか。 例えば、 変換前のファイル名が書かれたファイル(s.txt)と 変換後のファイル名が書かれたファイル(d.txt) がある場合、 abc.txtをqrs.txt d f.txtをtuw.txt ghi.txtをx z.txt  : にリネームしたいのですが もちろんtest1.batではうまくいきません。 ---test1.bat------------------- for /f %%a in (s.txt) do for /f %%b in (d.txt) do ren "%%a" "%%b" ------------------------------ ---s.txt---------------------- abc.txt d f.txt ghi.txt : ---d.txt---------------------- qrs.txt tuw.txt x z.txt : ------------------------------ 以下の sd.txt のように1つのファイルにして test2.bat のようにすればできますが s.txt と d.txt の2つのファイルのままで処理するには どのように記述すればよいのでしょうか。 ---test2.bat------------------- for /f "tokens=1,2 delims=," %%a in (sd.txt) do ren "%%a" "%%b" ---sd.txt---------------------- abc.txt,qrs.txt d f.txt,tuw.txt ghi.txt,x z.txt : ------------------------------- よろしくお願いします。(Windows7)

  • バッチコマンドを作りたい

    MS-DOSでのバッチコマンドについての質問です。 パスを引数で指定して、そのパスのディレクトリ以下(サブディレクトリも含む)のファイル名を全て取得し、加工して表示するバッチを作りたいのですが・・。 例えばコマンド名を jcm をすると C:\>jcm C:\temp と入力すると(「C:\temp」は引数)、C:\temp以下(サブフォルダも含めて)にある全てのファイル名を取得し、ファイル名がA.txt,B.txtだったとすると java A.txt java B.txt のように加工して表示したのです。 バッチファイルの中身はどのように記述すればよいでしょうか?

  • バッチファイルでテキストファイル読込

    バッチファイルにてテキストファイルを一行読込みたいのですが、 「,」までの位置しか取得できません。 現状の該当箇所のコマンドと読込むテキストは以下になります。 [実行するコマンド] For /F "delims=" %%i in (read.txt) Do Call :Sub %%i :Sub set DATA=%1 echo %DATA% [読込むテキスト read.txt] "111","222","333","444" "111","222","333","444" [結果] "111" 結果の通り、カンマまでしか取得できていない状態です。 どなたかご教授の方、よろしくお願い致します。