技術とか戦略とか

IT技術者が技術や戦略について書くブログです。

Windowsバッチのfindstr実行と結果判定は1行でまとめられないので代替案提示

言いたいことをまとめると、
WindowsバッチをExcelから生成するため、findstrの実行と結果判定(ERRORLEVELの判定)を1行でやりたかったができなかった。仕方ないのでfindstrと結果判定の間に特殊な記号を入れ、その記号をまとめて改行コードに置換することで対応した。」
です。
 
これで話が通じるのであれば、以降は読まなくて良いです。
 
--------------------
 
実務で「ファイル中に特定の文字列が存在する場合のみ、そのファイルに対して特定の処理を行う」ということをする必要が出てきました。
これは、findstrとif(変数「ERRORLEVEL」を判定)を組み合わせることで実現できます。
具体的には、以下のように実現できます。
 
--------------------
 
【バッチファイル】
・C:\tmp\testOK.bat
rem if文が真になり、ファイルがリネームされる
findstr "hoge" C:\tmp\hoge.txt > NUL
if "%ERRORLEVEL%" == "0" (move C:\tmp\hoge.txt C:\tmp\hoge2.txt)

rem if文が偽になり、ファイルがリネームされる
findstr "hoge" C:\tmp\fuga.txt > NUL
if "%ERRORLEVEL%" == "0" (move C:\tmp\fuga.txt C:\tmp\fuga2.txt)

pause
 
【対象ファイル】
・C:\tmp\hoge.txt
hoge
 
・C:\tmp\fuga.txt
fuga
 
【実行結果】
C:\tmp>rem if文が真になり、ファイルがリネームされる

C:\tmp>findstr "hoge" C:\tmp\hoge.txt  1>NUL

C:\tmp>if "0" == "0" (move C:\tmp\hoge.txt C:\tmp\hoge2.txt )
        1 個のファイルを移動しました。

C:\tmp>rem if文が偽になり、ファイルがリネームされる

C:\tmp>findstr "hoge" C:\tmp\fuga.txt  1>NUL

C:\tmp>if "1" == "0" (move C:\tmp\fuga.txt C:\tmp\fuga2.txt )

C:\tmp>pause
続行するには何かキーを押してください . . .
 
【実行後のファイル】
C:\tmp\hoge.txt は C:\tmp\hoge2.txt へリネーム。
C:\tmp\fuga.txt はそのまま。
 
--------------------
 
問題はここからです。
このfindstrとifのセットは、1000個ぐらい必要です。
Excelにその1000個の条件はまとめられているのですが、手作業で転記していては日が暮れてしまいます。
 
そこで、以下のようにfindstrとifを1行でまとめることで、Excelから簡単に(自動的に)コマンドを作れるようにしました。
しかし、これだと上手く動きませんでした。
理由は、findstrの結果が返ってくるよりも先に、変数「ERRORLEVEL」の中身が展開されてしまうからです。
(そういえばWindowsバッチはそのような挙動でしたね…)
 
--------------------
 
【バッチファイル】
・C:\tmp\testNG.bat
rem if文が真になり、ファイルがリネームされる
findstr "hoge" C:\tmp\hoge.txt > NUL & if "%ERRORLEVEL%" == "0" (move C:\tmp\hoge.txt C:\tmp\hoge2.txt)

rem if文が偽になり、ファイルがリネームされない
rem →「%ERRORLEVEL%」がfindstr実行前に展開されてしまうためリネームされる
findstr "hoge" C:\tmp\fuga.txt > NUL & if "%ERRORLEVEL%" == "0" (move C:\tmp\fuga.txt C:\tmp\fuga2.txt)

pause
 
【対象ファイル】
・C:\tmp\hoge.txt
hoge
 
・C:\tmp\fuga.txt
fuga
 
【実行結果】
C:\tmp>rem if文が真になり、ファイルがリネームされる

C:\tmp>findstr "hoge" C:\tmp\hoge.txt   1>NUL  & if "0" == "0" (move C:\tmp\hoge
.txt C:\tmp\hoge2.txt )
        1 個のファイルを移動しました。

C:\tmp>rem if文が偽になり、ファイルがリネームされない

C:\tmp>rem →「0」がfindstr実行前に展開されてしまうためリネームされる

C:\tmp>findstr "hoge" C:\tmp\fuga.txt   1>NUL  & if "0" == "0" (move C:\tmp\fuga
.txt C:\tmp\fuga2.txt )
        1 個のファイルを移動しました。

C:\tmp>pause
続行するには何かキーを押してください . . .
 
【実行後のファイル】
C:\tmp\hoge.txt は C:\tmp\hoge2.txt へリネーム。
C:\tmp\fuga.txt は C:\tmp\fuga2.txt へリネーム。
 
--------------------
 
結局、バッチファイルの「&」を「\r\n」へ置換することで対応しました。
サクラエディタで1000個一気に置換したので、手作業は免れました。