我希望在存储在文件夹和所有子文件夹中的一组文件中捕获项目版本。
使用:
@echo off<br>
findstr /s "ProjectVersion" C:\srm2\reg\*.cpf > C:\RESULTS.txt
返回文件夹中的每个.cpf文件。
e.g。
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 :(得分:1)
我在this post复制了答案,表明:&#34;你可以在Batch中编写一个递归算法,它可以精确控制你在每个嵌套子目录中所做的事情&#34; ,并稍微修改它以解决这个问题。该方法与其他答案相同:遍历树并在每个子文件夹中执行findstr
,仅使用按上次修改日期排序的第一个文件;区别在于此过程是通过代码显式实现的,而不是通过for /R
或dir /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
答案 1 :(得分: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"
进行测试。根据需要进行调整。
答案 2 :(得分: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
(将收到当前迭代目录中的最新文件),LINE
(将在文件中接收与搜索字符串匹配的行),reg*.cpf
的当前迭代目录,ProjectVersion
。最后,检查变量LINE
是否空虚,如果不是,则echo
输出包含文件路径,冒号和找到的行的行。
请注意,所有输出都会重定向到文件C:\results.txt
。
已经选择了使用子例程的方法,因为有一个goto
命令用于在第一次迭代时终止某个for
循环(参见上面的描述),但不是全部。 goto
实际上会破坏它所放置的所有块上下文,甚至是所有嵌套的上下文。 for
循环只是一种块命令,如if
子句,或简单的分组命令()
。使用子程序可以防止主程序块被子程序中放置的goto
破坏。