2015-11-13 45 views
0

我正在尋找捕獲存儲在文件夾和所有子文件夾中的一組文件中的項目版本。如何讓findstr過濾「上次修改」的文件?

使用:

@echo off<br> 
findstr /s "ProjectVersion" C:\srm2\reg\*.cpf > C:\RESULTS.txt 

返回文件夾中的每個文件.cpf。

例如

C:\srm2\reg\132L\132L-20151111-150804.cpf: <ProjectVersion Major="8" Minor="0" Build="22" Revision="20312" /> 
C:\srm2\reg\132L\132L.cpf: <ProjectVersion Major="11" Minor="0" Build="0" Revision="20312" /> 
C:\srm2\reg\132L\132L18122014121012.cpf: <ProjectVersion Major="8" Minor="0" Build="22" Revision="20312" /> 
C:\srm2\reg\132L\132L18122014121731.cpf: <ProjectVersion Major="8" Minor="0" Build="22" Revision="20312" /> 
C:\srm2\reg\DANNY\DANNY-20151112-134545.cpf: <ProjectVersion Major="11" Minor="0" Build="0" Revision="0" /> 
C:\srm2\reg\DANNY\DANNY-20151113-083530.cpf: <ProjectVersion Major="11" Minor="0" Build="0" Revision="0" /> 
C:\srm2\reg\DANNY\DANNY-20151113-085621.cpf: <ProjectVersion Major="11" Minor="0" Build="0" Revision="0" /> 
C:\srm2\reg\DANNY\DANNY-20151113-102018.cpf: <ProjectVersion Major="11" Minor="0" Build="0" Revision="0" /> 
C:\srm2\reg\DANNY\DANNY.cpf: <ProjectVersion Major="11" Minor="0" Build="0" Revision="0" /> 

如何才能篩選只返回最後在每個子文件夾改性.cpf文件,因爲某些文件夾具有相同的文件的多個版本?

+0

請通過編輯您的帖子告訴我們您試過的東西! – aschipfl

回答

0
@ECHO OFF 
SETLOCAL ENABLEDELAYEDEXPANSION 
SET "sourcedir=U:\sourcedir" 
SET "lastdir=" 
FOR /f "delims=" %%a IN ('DIR /s /b /a-d /o-d "%sourcedir%\*.bat" ') DO IF "!lastdir!" neq "%%~dpa" (
FINDSTR /i "z" "%%a" >NUL 
IF NOT ERRORLEVEL 1 (
    ECHO(%%a 
    SET "lastdir=%%~dpa" 
) 
) 

GOTO :EOF 

您需要更改sourcedir的設置以適應您的情況。

您提供的一行代碼根本不起作用。

此過程僅以基本形式(僅限完整文件名)生成*.bat文件的目錄列表,但按逆日期順序排序並排除目錄名。

該報表在每個目錄名稱中都是反向日期/時間順序,因此任何目錄的第一個匹配文件名都是最新的文件。

如果目錄名稱已更改,則執行findstr以找到所需的鍵串。如果找到,errorlevel設置爲0,因此它不是1 or greater,因此文件名被回顯,並且lastdir被設置爲文件的目錄名。

我只是使用*.bat文件和搜索"z"在那些文件進行測試。根據需要調整。

0

你可以使用for /R /D遞歸遍歷所有目錄走,然後用dir /B /A:-D /O:-D返回每日期排序文件列表(最新的在前)和for /F解析它的輸出只取第一項,所以你只枚舉了一個最新的文件中的所有目錄:

@echo off 
setlocal EnableExtensions EnableDelayedExpansion 
> "C:\results.txt" (
    for /D /R %%D in ("C:\srm2\reg\*.*") do (
     call :SUB FILE LINE "%%~fD\*.cpf" "ProjectVersion" 
     if defined LINE (
      echo/!FILE!:!LINE! 
     ) 
    ) 
) 
endlocal 
exit /B 

:SUB var_file var_line pattern string 
set "%~1=" & set "%~2=" 
for /F "eol=| delims=" %%F in ('dir /B /A:-D /O:-D "%~3"') do (
    set "%~1=%%~fF" 
    for /F "delims=" %%L in ('findstr /L "%~4" "%%~fF"') do (
     set "%~2=%%L" 
     goto :EOF 
    ) 
    goto :EOF 
) 

讓我們來看看在子程序:SUB第一,其目的是每個每個目錄執行一次。這需要4個參數:

  • %~1)變量來保存所檢索的文件的路徑名,
  • %~2)變量來保存與搜索字符串匹配的行的名稱,
  • %~3 )獲取文件的排序列表的模式(最新的第一個)和
  • %~4)搜索字符串(預計每個文件至多出現一次)。

for /F循環解析命令dir /B /A:-D /O:-D "%~3",這實際上建立的文件的排序列表的輸出。循環想要遍歷每一行,但由於最後有一個goto :EOF,循環在第一次迭代之後被破壞,所以只處理第一個(因此是最新的)列表項目。此項目的路徑被分配給作爲參數給出的第一個變量。如果沒有項目與文件模式匹配,則該變量保持空白。

內部for /F循環解析搜索命令findstr的輸出。由於最多隻有一次搜索字符串出現,所以此循環最多隻能迭代一次。如果找到匹配項,則將包含的行分配給作爲參數給出的第二個變量。如果找不到匹配,變量保持空。

現在讓我們看看主程序。這通過使用for /D /R遞歸地遍歷給定的目錄樹並遍歷所有目錄。對於每一個子程序:SUB被調用時,在經過以下參數:

  • 變量名FILE(將獲得在當前itereted目錄中最新的文件),
  • 變量名LINE(將接收線相匹配的搜索字符串)文件,
  • 與文件模式reg*.cpf附加當前迭代目錄,
  • 所要求的搜索字符串ProjectVersion

最後,可變LINE抵抗空虛檢查,並且如果沒有,包含文件路徑,冒號和發現線的線是輸出由echo

請注意,所有輸出都被重定向到文件C:\results.txt

這種方法使用的子程序已經被選擇,這是因爲用於終止在其第一次迭代一個一定for環路goto命令(見以上描述),但不是所有的人。 goto實際上會破壞它所放置的所有塊上下文,甚至是所有嵌套的上下文。 for循環只是一種塊命令,如if子句,或簡單分組命令()。使用子程序可以防止主程序塊被置於子程序中的goto中斷。

+0

我做了一個小的返工,因爲我沒有看到'reg'和'*之間的反斜槓。cpf',所以我把'reg'作爲文件名的一部分而不是目錄;然而,功能代碼保持不變... – aschipfl

1

我抄在this post答案,這表明:「你可以寫在批遞歸算法,讓你的你在每一個嵌套的子目錄做精確控制」,並略微爲了解決這個問題,修改了它。該方法與其他答案相同:遍歷樹並在每個子文件夾中執行findstr,只有最後修改日期排序的第一個文件;區別在於此過程是通過代碼而不是通過for /Rdir /S命令實現的顯式

@echo off 
setlocal EnableDelayedExpansion 
cd C:\srm2\reg 
call :treeProcess > C:\RESULTS.txt 
goto :EOF 


:treeProcess 
set "output=" 
for /F "delims=" %%f in ('dir /B /A:-D /O:D *.cpf') do if not defined output (
    for /F "delims=" %%o in ('findstr "ProjectVersion" "%%f"') do set "output=!cd!\%%f: %%o" 
) 
if defined output echo !output! 

rem Recursive call 
for /D %%d in (*) do (
    cd %%d 
    call :treeProcess 
    cd .. 
) 

exit /b 
+0

偉大的做法,@Aacini,+1!這種遞歸調用的性能如何? – aschipfl

+0

在服務器上工作,但吐出ECHO是關閉了很多:) – Mick

+0

@Mick:這發生時,一個子文件夾沒有_not_有任何'* .cpf'文件!只需在代碼中的'echo!output!'之前添加'if defined output'。我已經在答案中做了這個... – Aacini

相關問題