2017-04-24 61 views
0

我想通過一個目錄循環並映射出可能被掩埋在其他目錄中的子目錄,並拉出最近創建的目錄。我在這裏有一個循環,它將進入設置的根目錄,並僅查看目錄,合併所有子目錄,按創建日期對它們進行排序,並讓循環將列表末尾的那個設置爲最最近有人迴應說。但是,由於某種原因排序不能正確執行。它不斷提取不是最新的目錄。我似乎無法確定這個問題。什麼可能導致這個?我是否正確使用排序?它不會將子目錄與其他目錄上的其他目錄進行比較嗎?任何幫助將不勝感激。批處理文件循環未顯示最近的目錄

@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'日期爲當前目錄的順序排序,所以你的代碼將選擇在最後一個目錄的最後創建的目錄名遇到過,不是最後創建-OF-所有的目錄和子目錄。如果需要最後創建的目錄名,則需要對提取的日期進行排序的目錄列表以yymmddhhmmss格式排序。不是特別難,但也不是一條線。考慮你想要創建日期還是最新更新日期 - 以及爲什麼你需要該目錄?你真的在尋找最後(創建)的文件嗎? – Magoo

+0

這就是我的想法。我不能只建立一個所有目錄的列表,然後按創建的日期對它們進行排序嗎?我的最終目標是找出最近創建的目錄,並在其中包含超過20個文件時發送電子郵件通知。我有腳本的所有其他方面的工作,只是不排序。 –

+0

如果他們都在同一個目錄中,是的。如果不是,則需要通過將日期字符串(需要知道使用哪種格式)分解爲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的列表(「備用」對括號包圍for允許重定向)

如果filename2存在(這將是每次運行後的第一個),然後找到filename1filename2之間的區別,使用/L文字,/v不匹配/i在此文件中不區分大小寫/x精確匹配/g:弦和每一個新的目錄名分配到%%a

接着掃描的"%%a"的目錄,只有文件,抑制file not found消息和計數返回線(/c計數/v線不匹配""空字符串)的數量。將re4sult分配給%%c,測試並選擇採取措施。

在所述重定向器之前插入記號^for ... %%c命令的命令要被執行的躲避轉向器使得它們被解釋爲一部分的命令要被執行,而不是for

+0

爲什麼不說'dir/b/s/ad'%sourcedir%\ *「>」%filename1%「'而不是使用'for/F'循環呢? – aschipfl

+0

@aschipfl爲什麼? '因爲我沒有想到它。是的 - 那會工作... – Magoo

0

dir /S /O命令排序每個單獨的子目錄的內容,並沒有辦法改變這種行爲。


一種可能的替代方法是在標準化的,可排序的,區域 - 和locale-使用wmic命令,這是有點慢,但能夠導出所述日期信息的(創建,最後修改,上次訪問)獨立格式:

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

所以下面兩個腳本使用一個for /D /R循環得到所有的(子)目錄,上面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% 

第二個存儲的每個目錄在名爲創建日期的變量,在下面的格式:

$20170424215505.000000+060=D:\Data 

對於排序,所述使用set命令。下面是代碼:

@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 "ERR=0" 
rem // Clean up variables beginning with `$`: 
for /F "delims==" %%C in ('2^> nul set "$"') do set "%%C=" 
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 (
       rem /* Assign currently iterated path to variable named of the 
       rem respective creation date preceded by `$`: */ 
       endlocal & set "$%%K=%%~D" 
      ) 
     ) 
    ) || (
     endlocal 
     rem // This is only executed in case a path contains both `)` and `,`: 
     >&2 echo ERROR: Could not handle directory "%%~D"! 
     set "ERR=1" 
    ) 
) 
rem /* Return all variables beginning with `$` in sorted manner using `set` command, 
rem remember last item of sorted list: */ 
for /F "tokens=1* delims==" %%C in ('2^> nul set "$"') do set "LASTDIR=%%D" 
rem // Return newest directory: 
echo "%LASTDIR%" 

endlocal 
exit /B %ERR%