FINDSTR和跳过文件夹

时间:2013-11-19 16:01:21

标签: windows batch-file findstr

我是Windows批处理编程和Stack Overflow的新手,所以请原谅我,如果我问任何对你经验丰富,才华横溢的人来说显而易见的事情。我正在使用Windows批处理(.bat)来查找包含某个字符串的文件findstr。但是,我正在尝试跳过目录中的某些文件夹。

setlocal EnableDelayedExpansion
set basedir=C:\folder

for /f %%g in ('dir /a:-h /b %basedir% ^| findstr /v "Projects" ^| findstr /v "Archive"') do (
    findstr /i /m /s /c:"request" %basedir%\%%g *.* > %basedir%\Projects\list.txt
)

当我查看list.txt,findstr的文件输出时,我发现我告诉它不要搜索的文件夹被搜索到了。也就是说,输出看起来像这样:

C:\folder\somefile.rtf
C:\folder\Requests\anotherfile.rtf
C:\folder\Projects\dontsearchme.txt
C:\folder\Archive\dontsearchmeeither.txt
C:\folder\Archive\Projects\dontsearchme.txt

如果它运行正常,则list.txt中只会包含C:\folder\somefile.rtfC:\folder\Requests\anotherfile.rtf。为了测试循环代码,我使用了以下内容:

setlocal EnableDelayedExpansion
set basedir=C:\folder

for /f %%g in ('dir /a:-h /b %basedir% ^| findstr /v "Projects" ^| findstr /v "Archive"') do (
    echo %basedir%\%%g
)

该代码按预期工作;它会跳过“项目”和“存档”文件夹。我认为问题与我如何调用findstr有关,但我无法确定我的方式错误。任何见解都会非常感激!

非常感谢! -Alex

4 个答案:

答案 0 :(得分:6)

FINDSTR / S选项使其搜索所有文件夹,从而绕过FOR循环的意图。

Stephan使用覆盖而不是附加模式成功诊断了代码中有关重定向的另一个问题。

但是有一种更简单的方法可以获得理想的结果。只需让FINDSTR搜索所有文件夹,并将结果通过管道传输到另一个FINDSTR,以删除包含不需要的文件夹的结果。由于没有循环,您可以安全地使用owverwrite模式进行重定向。

findstr /misl request "%basedir%\*" | findstr /liv "\\projects\\ \\archive\\" >"%basedir%\Projects\list.txt"

修改

上述简单的解决方案将浪费时间搜索稍后将被排除的文件夹。如果这些文件夹很大,这可能会浪费宝贵的时间。

以下脚本不会打扰扫描“%basedir%\ Projects”或“%basedir%\ Archive”文件夹。

@echo off
setlocal EnableDelayedExpansion
set basedir=C:\folder

>"%basedir%\Projects\list.txt" (
  findstr /mil request "%basedir%\*"
  for /f "eol=: delims=" %%F in (
    'dir /a:d-h /b %basedir% ^| findstr /vixl "projects archive"'
  ) do findstr /smil request "%basedir%\%%F\*"
)

如果您想要跳过名为“Projects”或“Archive”的所有文件夹,无论它们出现在树中的哪个位置,那么:

@echo off
setlocal EnableDelayedExpansion
set basedir=C:\folder

>"%basedir%\Projects\list.txt" (
  findstr /mil request "%basedir%\*"
  for /f "eol=: delims=" %%F in (
    'dir /s /a:d-h /b %basedir% ^| findstr /vir "[\\]projects[\\] [\\]archive[\\] [\\]projects$ [\\]archive$"'
  ) do findstr /mil request "%%F\*"
)

答案 1 :(得分:3)

我遇到了类似的问题:我需要使用findstr来搜索所有.js文件除了那些在node_modules文件夹中的文件(即,我想搜索我的代码,但不是任何导入的代码模块)。这是我使用的命令:

dir /S /B *.js | findstr /v /i node_modules | findstr /i /F:/ todo

打破这一点:

  • dir /S /B *.js将输出当前目录和所有子目录中所有.js文件的完整路径
  • findstr /v /i node_modules过滤该路径列表,并删除包含字符串" node_modules"的任何路径。 (/ v标志使得匹配的findstr输出行。)
  • findstr /i /F:/ todo - " / F:/"告诉findstr接受要从控制台搜索的文件路径列表。

因此,只有通过" node_modules"过滤器被搜索。

答案 2 :(得分:1)

你的问题是:通过重定向>,你每次都会覆盖你的list.txt;最后一次用空字符串覆盖它。 请改用>>(附加到文件)。你的其余代码正在为我工​​作。

答案 3 :(得分:0)

您的代码有几点难以理解。您想跳过文件夹,但for /f %%g in ('dir /a:-h /b %basedir%命令获取所有非隐藏名称,包括文件和文件夹。最后,您使用>来存储结果,因此只有最后findstr ... %%g的输出存储在该文件中。您必须使用>>代替Stephan指示。但是,我仍然不明白你是如何得到这个结果的!

我建议您修改代码以使其更简单,因此可能更容易跟踪并检测可能的错误。例如:

setlocal EnableDelayedExpansion
set basedir=C:\folder
set omitfolders=\Projects\Archive\
cd %basedir%
for /D %%g in (*) do (
   if "!omitfolders:\%%g\=!" equ "%omitfolders%" (
       findstr /i /m /s /c:"request" %basedir%\%%g\*.* >> %basedir%\Projects\list.txt
   )
)

if "!omitfolders:\%%g\=!" equ "%omitfolders%"命令测试omitfolders变量中的文件夹名称​​不是