2017-02-26 26 views
0

引数に指定されていない拡張子(.sysファイルを除く)を含むすべてのファイルを削除する必要があります。問題は私の変数の代入である。ここでバッチファイル指定された拡張子でファイルを削除する

は私のコマンドは(、複製のための謝罪ここで使用する方法がわからまたは文ではありませんでした)です:

@echo off 
cls 
cd test 
for %%f in (*.*) do (
    set exist = false 
    for %%a in (%*) do (
     if %%~xf == .%%a set exist = true 
     if %%~xf == .sys set exist = true 
    ) 
    if %exist% == false ( 
     del %%f 
    ) 
) 
pause 

は私が期待どおりに動作し、このコードを取得する方法上の任意の提案のために非常に感謝されます。

答えて

3

コードの主な問題は、変数の拡張です。バッチファイルでは、コマンドまたはコマンドブロック(括弧で囲まれた複数のコマンド)が読み取られると、それらは解析されて実行されます。解析フェーズ中に、変数読取り操作(%var%)が、変数内の値で置き換えられるコードから削除されます。これが完了すると、コマンドまたはブロックが実行されます。

これは、コードを実行するときに変数(コード内でexists)を変更すると、変数の読み取り操作がないため、同じコマンド/ブロック内では変更された値を取得できないことを意味します。実行フェーズを開始する前に変数内の値のみを返します。

これは、setlocal enabledelayedexpansionを使用して回避することができます。このコマンドを使用すると、変数を読み取るために使用する構文を%var%から!var!に変更することができます。構文解析フェーズではなく、コマンドが実行されるまで変数拡張を遅延させる必要があることをパーサーに示します。

だから、あなたのコードは

  • set var = valueset 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/falsedefined/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 
+1

非常に良いです。しかし、おそらくlfn vs sfnについての注意書きを追加してください。 – Magoo

+0

@Magooは、そのままでは、短いファイル名/拡張子に問題はありません。検索はファイルの拡張子を使って行われず、 '%%〜xf'は長い拡張子があればそれを検索します。 –

+0

@MCNDうわー!非常に義務づけられた、それはとても有益でした! – Igor

関連する問題