プロが教える店舗&オフィスのセキュリティ対策術

特定月のログを削除する。DOSコマンドを作成したのですが旨く削除されません。
アドバイスをお願いします。

set timestp = %2010/03%

for %a in ( c:\logs ) do set fdate=%~ta (
set fdate=%fdate:~0,7%

rem 削除処理
if %fdate:~-7%==%timestp% del %a ← ★

)

★の処理で対象月のファイルを削除しようとしているのですが
 実際には削除処理が実行されている形跡がなりません・・・

よろしくお願いします。

A 回答 (2件)

いくつか指摘点があります。



>set timestp = %2010/03%

これは変数にセットする値なので 2010/03 ですよね。
(%%は不要)

>c:\logs

これだと取得できるのは、c:\logsディレクトリ自体のタイムスタンプになります。
logs内のログファイルをループして処理したいのであれば、

c:\logs\*

にする必要があると思います。

それと、カッコ内のコマンドをFORによってループさせるのであれば、左カッコの位置が違います。
doの後ろに左カッコが必要です。

以上を鑑み、バッチの中はこうなります。
(バッチで試したので %a → %%a 、%~ta → %%~taで記述しています)



@echo off

set timestp=2010/03

for %%a in ( C:\logs\* ) do (

set fdate=%%~ta
set fdate=%fdate:~0,7%

rem DEBUG
echo target_ts:%timestp%
echo target_file_path:%%a
echo target_file_ts:%fdate%

rem 削除処理
if "%fdate:~-7%" == "%timestp%" del "%%a"

)
    • good
    • 0

No.1さんの指摘と重複しますが


・変数に代入する値を%で囲む必要はありません。
・set timestp = %2010/03% のように = の前後に空白を入れると、その空白を含んだ変数名に代入されてしまいます。
・バッチでfor文の変数を記述するときは%%aのように%を2つ重ねて記述します。
・%fdate:~-7% は単に%fdate%でいいのでは(その前に先頭から7文字取り出しています)

また、No.1さんの指摘したfor文のファイルの指定については同意見で、c:\logsの中にログファイルが複数あると解釈しました。

ただ、No.1さんの例示した内容でも上手く動きません。

for文のループで実行する内容を( )でくくって複文とした場合、()内の環境変数はfor文が実行された時点で展開(中身の値に置き換え)されます。
したがって、set fdate=%fdate:~0,7% や %fdate:~-7%などの記述はすべて、for文が実行された時点の値(つまり空)になってしまうため意図どおりには変換されません。
(set /? のヘルプに説明があります)

ループ内で値の変化を反映させるためには、環境変数の遅延展開を使用するか、CALL文に引数を渡してサブルーチンで処理させるのが定番です。

以下に CALL 文での記述例を示します。
CALL文の引数には %%~fa でファイルのフルパスを渡しています。
サブルーチン側では、%1 がファイルのフルパス、%~t1がタイムスタンプになります。
Windows XP で確認しました。



:------------------------------------------------ sample.bat
echo off
set timestp=2010/03

for %%a in ( c:\logs\* ) do call :sub "%%~fa"
exit /b

:sub
set fdate=%~t1
if "%fdate:~0,7%"=="%timestp%" del %1
goto :EOF
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!