递归目录搜索中如何使用CMD正则限制输出

问题描述 投票:0回答:2

我需要为代码存储库中存储不一致的一组文件夹创建动态报告;有些的关键特征向下两层,有些向下三层,还有一些向下四层以上。

  • 最接近一致性的是all我需要的关键文件夹 报告包含“[...]d_d[...]”或“[...]dd_dd[...]”(其中 d 是数字);这些匹配的字符串可能出现在中间或末尾,但绝不会出现在开头。
  • 一旦找到,我需要列出 only 关键文件夹和 not 它的任何 子文件夹,即使它的一个或多个子文件夹也碰巧也 包含任何一个相同的模式。
  • 由于生成递归列表的方式,所有结果都会有一个终止斜线,但我不想得到斜线以外的任何东西;老实说,我不在乎终止斜线是否是报告的一部分。
  • 由于不一致,valid 输出中可能有三个、四个、五个或更多斜杠。

这是几个实例的简短示例,我需要以 +++ 为前缀的结果,并且需要 not 包括以 ---

为前缀的列表
+++ A1B2C3/ABC_Core/ABC_HIJ_R71_00_00/
--- A1B2C3/ABC_Core/ABC_HIJ_R71_00_00/QR-HIJ-Outbound-123-Svc/SharedResources/WXYZ/Client/TU4_987_864X22Dat/
+++ A1B2C3/ABC_Core/ABC_HIJ_R72_00_00/
--- A1B2C3/ABC_Core/ABC_HIJ_R72_00_00/QR-HIJ-Outbound-123-Svc/SharedResources/WXYX/Client/TU4_987_864X22Dat/
+++ A1B2C3/ABC_Core/ABC_HIJ_R73_00_00_WidgetMod/
--- A1B2C3/ABC_Core/ABC_HIJ_R73_00_00_WidgetMod/QR-HIJ-Outbound-123-Svc/
+++ D4E5F6/QRWidgetFlow_R_1_0_0_DMND0903212-ErrorReports/

我已经尝试了几种变体

findstr /e /r /c:"[0-9][0-9]_[0-9][0-9][^0-9/]*/" /c:"[0-9]_[0-9][^0-9/]*/"

但每次我改变它时,我要么获得额外的子文件夹,要么丢失我以前拥有的关键文件夹。

任何帮助将不胜感激。

batch-file cmd findstr
2个回答
0
投票
@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION 

rem The following setting for the directory is a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.

SET "sourcedir=u:\your files"
SET "tempfile=%tmp%\afilename"
SET "numerics=0-9"
SET "lastkey=?"

(FOR /d /r "%sourcedir%" %%e IN (*_*) DO ECHO %%e)>"%tempfile%"
FOR /f "delims=" %%e IN ('sort "%tempfile%"') DO (
 FOR %%y IN ("%%e\.") do (
  rem does leaf pass test does not start 9_9 or 99_99 
  ECHO %%~nxy|FINDSTR /b /r /c:"[%numerics%]_[%numerics%]" /c:"[%numerics%][%numerics%]_[%numerics%][%numerics%]">NUL
  IF ERRORLEVEL 1 (
   rem does not start 9_9 or 99_99 - does it contain 9_9 or 99_99 ?
   ECHO %%~nxy|FINDSTR /r /c:"[%numerics%]_[%numerics%]" /c:"[%numerics%][%numerics%]_[%numerics%][%numerics%]">NUL
   IF NOT ERRORLEVEL 1 (
    rem contains 9_9 or 99_99
    CALL :report "%%e"
   )
  )
 )
)

DEL "%tempfile%"

GOTO :EOF

:report
SET "reportme=%~1"
SET "reportme=!reportme:%lastkey%=!"
IF "%reportme%" neq %1 GOTO :eof
ECHO %~1
SET "lastkey=%~1"
GOTO :eof

在应用于真实数据之前,始终对照测试目录进行验证。

获取完整的子目录列表并将其存储在临时文件中。

从临时文件的排序版本中读取每个目录名,并导出叶名。如果叶名不以目标字符串开头,但确实包含其中一个字符串,那么它就是要报告的候选者。

报告查看作为

%1
传递的引用目录名是否包含最后报告的名称。如果是,则忽略它,否则报告并将其设置为最后报告的名称。

由于名称已排序,“关键”目录的所有子目录将在列表中位于该目录之后。

我相信要匹配的字符串实际上可能需要是 _9_9 或 _99_99,因为 9_9 本身会匹配“A1B2C3/ABC_Core/ABC_HIJ_R7xxxxx/QR-HIJ-Outbound-123-Svc/SharedResources/WXYZ/Client/TU4_9 87_864X22数据/"


-1
投票

如果要过滤现有的文件夹列表,停止找到的文件夹的任何子文件夹的规则也需要使用先行组,

findstr
不支持。

您可以改用 powershell 的

-match
。例如:

foreach($line in Get-Content C:\Source\2.txt) {
  if($line -match '^(?!.*\d_\d.*\/.*\d_\d).*\d_\d[^\/]*\/$') {
    Write-Host $line  
  }
}

这里正则表达式如下:

  • ^(?!.*\d_\d.*\/.*\d_\d)
    - 检查名称中是否没有带有
    \d_\d
    模式的嵌套文件夹,
  • .*\d_\d[^\/]*\/
    - 检查路径中的最后一个文件夹名称是否包含模式
    \d_\d
  • $
    - 检查包含模式
    \d_\d
  • 的文件夹名称后没有其他文件夹名称

可以看到匹配的演示here.

© www.soinside.com 2019 - 2024. All rights reserved.