我希望捕获一组存储在文件夹和所有子文件夹中的文件的项目版本。
使用:
@echo off<br>
findstr /s "ProjectVersion" C:\srm2\reg\*.cpf > C:\RESULTS.txt返回文件夹中的每个.cpf文件。
例如:
C:\srm2\reg \132L\reg\132L\reg\13804.C:C:C:\srm2\reg\132L\reg\132L 18122014121012.cpf:C:C:\srm2\reg\reg132L\reg\reg132L\reg2014121731.cpf:C:\srm2\dann-20151112-134545.cpf:C:\srm2\reg丹尼-20151113-0835cpf:C:C:\srm2\reg\reg\rg丹尼-20151113-08566cpf:C:srm2\reg\rg丹尼-20151113-08565ppf:C:丹尼-20151113-102018.cpf: C:\srm2\reg\DANNY\DANNY.cpf:
如何筛选以仅返回每个子文件夹.cpf中的上一次修改的文件,因为有些文件夹有多个相同文件的版本?
发布于 2015-11-13 17:02:52
我在this post上复制了答案,它表明:“您可以批量编写递归算法,使您能够精确地控制在每个嵌套子目录中所做的操作”,并对其进行了稍微的修改,以解决这个问题。这种方法与其他答案是一样的:遍历树,在每个子文件夹中执行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发布于 2015-11-13 14:51:48
@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" witin这些文件进行测试。根据需要调整。
发布于 2015-11-13 15:00:49
您可以使用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破坏主例程的块。
https://stackoverflow.com/questions/33694797
复制相似问题