コードの主な問題は、変数の拡張です。バッチファイルでは、コマンドまたはコマンドブロック(括弧で囲まれた複数のコマンド)が読み取られると、それらは解析されて実行されます。解析フェーズ中に、変数読取り操作(%var%
)が、変数内の値で置き換えられるコードから削除されます。これが完了すると、コマンドまたはブロックが実行されます。
これは、コードを実行するときに変数(コード内でexists
)を変更すると、変数の読み取り操作がないため、同じコマンド/ブロック内では変更された値を取得できないことを意味します。実行フェーズを開始する前に変数内の値のみを返します。
これは、setlocal enabledelayedexpansion
を使用して回避することができます。このコマンドを使用すると、変数を読み取るために使用する構文を%var%
から!var!
に変更することができます。構文解析フェーズではなく、コマンドが実行されるまで変数拡張を遅延させる必要があることをパーサーに示します。
だから、あなたのコードは
set var = value
がset var=value
に変更されていることを
@echo off
setlocal enabledelayedexpansion
cls
cd test
for %%f in (*.*) do (
set "exist=false"
for %%a in (%*) do (
if /i "%%~xf" == ".%%a" set "exist=true"
if /i "%%~xf" == ".sys" set "exist=true"
)
if "!exist!"=="false" (
del "%%f"
)
)
pause
ノートのようなものである可能性があります。スペースが重要である、あなたは値[space]value
でvar[space]
という変数を定義したすべての変数の代入は、変数の値に含まれる不要な結末スペースを防ぐために引用されています。スペースを含めると、==
テストが失敗する可能性があります。注意深くする必要はありませんが、それは良い習慣です。
引用符は、ファイル名や拡張子にスペースの問題
%exists%
しばらく同じブロック内(for %%f
)
- ように変更された値を取得することができる
!exists!
に変更されたことを防止するために含まれていますif
拡張子の比較には、大文字と小文字を区別しないテスト用のスイッチ/i
が含まれています。
また遅れ拡張を有効にしたとき、パーサが可変の読み出し動作の一部としてそれを見るように、!
文字が問題となることに注意してください。この文字を含む可能性のあるファイルや拡張子がある場合は、遅延拡張が問題になります。これを行うことはできますが、実際に必要な場合は遅延拡張を有効にし、必要がない場合は再度無効にする必要があります。
@echo off
setlocal disabledelayedexpansion
cls
cd test
for %%f in (*.*) do (
set "exist=false"
for %%a in (%*) do (
if /i "%%~xf" == ".%%a" set "exist=true"
if /i "%%~xf" == ".sys" set "exist=true"
)
setlocal enabledelayedexpansion
if "!exist!"=="false" (
endlocal
del "%%f"
) else (
endlocal
)
)
pause
しかし、あなたの場合のように、あなたが2つのだけの値と値の間の変数値を変更しているが無関係である、それが唯一のフラグであり、あなたは、変数内の遅延拡張と真の価値を無視して使用することができます変数に値が含まれているかどうかをテストする代替構文、if defined
拡張子は、引数のいずれかと一致する場合は、あなたのtrue/false
がdefined/not defined
テスト
@echo off
setlocal enableextensions disabledelayedexpansion
cd test
for %%f in (*) do (
set "removeFile=1"
for %%x in (sys %*) do (
if /i "%%~xf"==".%%~x" set "removeFile="
)
if defined removeFile del "%%f"
)
pause
することができ、変数の内容はつまり、今の変数が定義されていない、削除されます。 filesytem要素を扱う場合マグーのコメントに適応する
編集は
、ファイル/フォルダの選択で予期しない動作を確認することが可能です。
従来の名前付けに従わないファイルとフォルダ(名前は最大8文字、拡張子は最大3文字、特殊文字はない、スペースなし)は、ロングネームとして知られていますが、また、長い名前に関連付けられた短い名前8.3
があります。 dir
コマンドの/x
スイッチを使用して確認できます。
ワイルドカード検索が実行されると、これらの短い名前がチェックされ、ファイル/フォルダが長いファイル名または拡張子が選択されたワイルドカード表現に一致しないが、ワイルドカードと一致する短い名前または拡張子。短い名前または拡張子場合
がfor
ループ内で処理する必要がある、それらを取得するためにfor
交換可能なパラメータ(例。%%f
)で使用される修飾子は確か
%%~snxf Short name and short extension of the element being referenced by %%f
%%~snf Short name of the element being referenced by %%f
%%~sxf Short extension of the element being referenced by %%f
非常に良いです。しかし、おそらくlfn vs sfnについての注意書きを追加してください。 – Magoo
@Magooは、そのままでは、短いファイル名/拡張子に問題はありません。検索はファイルの拡張子を使って行われず、 '%%〜xf'は長い拡張子があればそれを検索します。 –
@MCNDうわー!非常に義務づけられた、それはとても有益でした! – Igor