2017-04-24 16 views
0

私は1つのディレクトリをループして、他のディレクトリに埋め込まれている可能性のあるサブディレクトリを取り出し、最近作成されたディレクトリを取り出します。私はここにループがあり、これは設定されているルートディレクトリに移動し、ディレクトリのみを参照し、すべてのサブディレクトリを組み込み、作成日によってソートし、ループの最後にリストを設定します最近のものはエコーアウトされます。しかし、何らかの理由でソーティングが正しく行われません。直近ではないディレクトリを引き出します。私は問題を特定することができない。これを引き起こす原因は何ですか?並べ替えを正しく使用していますか?他のレベルのサブディレクトリと他のディレクトリを比較しませんか?どんな助けでも大歓迎です。バッチファイルのループに最新のディレクトリが表示されない

@ECHO OFF 
SET dir=C:\Users\Darren\Google Drive\ 
echo %dir% 
FOR /F "delims=" %%i IN ('dir "%dir%" /b /s /ad-h /t:c /od') DO (
echo %%i 
SET a=%%i) 
SET sub=%a% 
echo Most recent subfolder: %sub% 
+0

'dir/od'は現在のディレクトリの日付の順番でソートされるため、最後に作成されたディレクトリ名ではなく、すべてのディレクトリとサブディレクトリ。最後に作成されたディレクトリ名が必要な場合は、yymmddhhmmss形式に日付を抽出したディレクトリのリストをソートする必要があります。特に難しくはないが、1行ではない。作成日か最終更新日かを検討し、そのディレクトリをなぜ必要としますか?実際に最後の(作成された)ファイルを探していますか? – Magoo

+0

それは私が考えたものです。私はすべてのディレクトリのリストを作成し、作成した日付順に並べ替えることができませんでしたか?私の最終的な目標は、作成された最新のディレクトリを見つけて、20個以上のファイルがある場合は電子メール通知を送信することです。私は、スクリプトの他のすべての側面は、並べ替えではなく、動作しています。 –

+0

すべてが同じディレクトリにある場合は、yesです。そうでない場合は、日付文字列を分解して日付を比較する必要があります(使用するフォーマットを知っている必要があります)yymm ...別の方法として、ディレクトリツリーをファイルに記録し、新しいディレクトリ表示される点は、新しいディレクトリがすべて親を共有していない場合でも、日付を比較して並べ替える必要があるということです。 > 20個のファイルを含む新しいディレクトリのすべてを通知したくないですか?それは簡単に構築できるはずです。 – Magoo

答えて

0
@ECHO OFF 
SETLOCAL 
SET "sourcedir=U:\sourcedir" 
SET "filename1=%sourcedir%\q43579378.txt" 
SET "filename2=%sourcedir%\q43579378_2.txt" 
(
FOR /f "delims=" %%a IN (
'dir /b /s /ad "%sourcedir%\*" ' 
) DO ECHO %%~a 
)>"%filename1%" 

IF EXIST "%filename2%" (
FOR /f "delims=" %%a IN ('findstr /L /V /i /x /g:"%filename2%" "%filename1%"') DO (
    FOR /f %%c IN ('dir /b /a-d "%%a\*" 2^>nul^|find /c /v "" ') DO (
    IF %%c gtr 20 ECHO(send email directory %%a has %%c files 
) 
) 
) 

MOVE "%filename1%" "%filename2%" >nul 
GOTO :EOF 

私はsourcedirとしてテストディレクトリを使用。もちろん、スキャンするディレクトリと同じである必要はなく、ファイル名は好きなものにすることができます。

最初for

現在 filename1に既存の絶対dirctorynamesのリストを構築する最初の後にすべての実行であろう

filename2が存在する場合((「スペア」はforを囲む括弧一対のリダイレクションを可能にします) )、このファイル内の/i大文字と小文字を区別しない/x完全一致/g:文字列と一致し、%%aにそれぞれの新しいディレクトリ名を割り当てないリテラル/L/vを使用して、filename1filename2の違いを見つけます。

その後"%%a"のディレクトリをスキャンし、file not foundメッセージを抑制し、返された行(/c/vラインが""空の文字列に一致しない)の数をカウントし、ファイルのみ。 re4sultを%%cに割り当て、テストしてアクションを実行する場所を選択します。それらはコマンドツー・実行することなく、forの一部として解釈されるように、コマンドツー実行さfor ... %%cコマンドでリダイレクタ前

キャレット^はリダイレクタを逃れます。

+0

これに 'for/F'ループを使用するのではなく、なぜ' dir/b/s/ad "%sourcedir%\ *"> "%filename1%" ' – aschipfl

+0

@aschipflなぜですか?私はそれを考えなかったからです。うん - それはうまくいくだろう... – Magoo

0

dir /S /Oコマンドは、すべてのサブディレクトリの内容を個別にソートするため、その動作を変更する方法はありません。


可能な代替のアプローチは、標準化されたソート、領域 - およびロケールに少し遅いが、日付情報を導出することが可能であるwmicコマンド、(作成、最終更新、最終アクセス)を使用することです独立したフォーマット:だから以下

wmic FSDir where Name="D:\\Data" get CreationDate /VALUE 
wmic FSDir where (Name="D:\\Data") get CreationDate /VALUE 

がでソートを行うには、それらの出力と、単純なコマンドをキャプチャするために、すべての(サブ)ディレクトリを取得するためにfor /D /Rループを使用して2つのスクリプト、上記wmicコマンドライン、for /Fあります年齢。


最初のものは、次の形式で、その作成日と一緒に、すべてのディレクトリを収集するための一時ファイルを作成します。

ソートするための
20170424215505.000000+060 D:\Data 

sortコマンドが使用されています。

@echo off 
setlocal EnableExtensions DisableDelayedExpansion 

rem // Define constants here: 
set "_ROOT=%~1" & rem // (use first command line argument as the root directory) 
set "_PATTERN=*" & rem // (search pattern for directories; `*` matches all) 
set "_TMPF=%TEMP%\%~n0_%RANDOM%.tmp" & rem // (specify a temporary file) 

rem // Write list of directory paths preceded by their creation dates to temporary file: 
> "%_TMPF%" (
    set "ERR=0" 
    rem // Enumerate all matching directories recursively: 
    for /D /R "%_ROOT%" %%D in ("%_PATTERN%") do (
     rem // Store currently iterated directory path: 
     set "DIRPATH=%%~D" 
     rem // Toggle delayed expansion to avoid trouble with the exclamation mark: 
     setlocal EnableDelayedExpansion 
     (
      rem /* Capture `wmic` output to query creation date of currently iterated 
      rem directory in locale-dependent and sortable format: */ 
      for /F "tokens=2 delims==" %%L in (' 
       rem/ Do two attempts, because one approach can handle `^)` and one can handle `,`; ^&^
        rem/ note that `wmic` cannot handle paths containing both of these characters: ^&^
        2^> nul wmic FSDir where Name^="!DIRPATH:\=\\!" get CreationDate /VALUE ^|^|^
        2^> nul wmic FSDir where ^(Name^="!DIRPATH:\=\\!"^) get CreationDate /VALUE 
      ') do (
       rem // Do nested loop to avoid Unicode conversion artefacts (`wmic` output): 
       for /F %%K in ("%%L") do echo(%%K !DIRPATH! 
      ) 
     ) || (
      rem // This is only executed in case a path contains both `)` and `,`: 
      >&2 echo ERROR: Could not handle directory "!DIRPATH!"^^! 
      set "ERR=1" 
     ) 
     endlocal 
    ) 
) 
rem /* Return content of temporary file in sorted manner using `sort` command, 
rem remember last item of sorted list; clean up temporary file: */ 
for /F "tokens=1*" %%C in ('sort "%_TMPF%" ^& del "%_TMPF%"') do set "LASTDIR=%%D" 
rem // Return newest directory: 
echo "%LASTDIR%" 

endlocal 
exit /B %ERR% 

次の形式で、作成日付の名前の変数に2番目の店舗ごとのディレクトリ:ソートに

$20170424215505.000000+060=D:\Data 

、ここでは、コードですsetコマンドが使用されます。

関連する問題