如何在 windows 批次中找到与 findstr 的精确匹配

How can find exact match with findstr in for of windows batch

我唯一想做的是在 windows 批处理中,使用 findstr.

获取 dir 命令的输出

如果我知道这是人生中最复杂的事情,我就不会尝试了。

我所做的是,首先,编写我需要其输出的命令:

dir /A D:\path | findstr mykeyword

但实际上我需要“keyword”的精确匹配,所以我找到了这个:

所以,我现在的命令是:

dir /A D:\path | findstr "\<mykeyword\>"

我已经试过了,输出是我想要的。

那么,如何在批处理文件中获取它的输出呢?当然,直觉的尝试是行不通的。它一定很复杂。所以,我发现了这个:

一个循环只是为了设置一个变量。无论如何,这带来了另一个并发症。现在我不能正确地写 "\<mykeyword\>",转义特殊字符,首先 ' 然后 ",在 For 命令中,正如 anwser 所建议的那样。

我试过这个:

For /F %%A in ('"dir /A %path_to_look% | findstr ""\^<mykeyword\^>"""') do set res1=%%A

这个returns没什么。 res1 为空。

那么,如何在 For 命令中找到与 findstr 的完全匹配?

我的解决方案一直使用 ^| 而不是 |

这使得在 in().

中仅使用 ' 而不是 '" 成为可能

所以现在我可以写 findstr "" 而无需转义 " 字符,这是我唯一试图找到的东西。

所以,

之前:

For /F %%A in ('"dir /A %path_to_look% | findstr ""\<mykeyword\>"""') do set res1=%%A

据说 " 可以转义为 "" 但此代码不起作用。

所以,

之后:

For /F %%A in ('dir /A %path_to_look% ^| findstr "\<mykeyword\>"') do set res1=%%A

这确实有效。

(不过,换句话说,“如何在 in ('""') 中使用 findstr 时转义特殊字符问题仍然是个谜。)

是的,要捕获命令行的输出:

dir /A %path_to_look% | findstr "\<mykeyword\>"

通过 for /F loop, you could use (note the escaped pipe ^| 这是必需的,因为它暴露给未加引号的命令处理器):

for /F %%A in ('dir /A %path_to_look% ^| findstr "\<mykeyword\>"') do set res1=%%A

或(加上周围的引号,导致管道出现引用但 redirection symbols < and > 未引用,因此需要转义):

for /F %%A in ('"dir /A %path_to_look% | findstr "\^<mykeyword\^>""') do set res1=%%A

了解 for /F 通过 cmd /C 执行给定的命令并了解其处理引号的规则(键入 cmd /? 并阅读用法文本)可能有助于理解其工作原理也是。

您可能已经注意到,第二种方法会反转整个命令行的引用状态,但这可以通过转义 outer-most 引号来避免:

for /F %%A in ('^"dir /A %path_to_look% ^| findstr "\<mykeyword\>"^"') do set res1=%%A

但是,我建议仅在确实需要 outer-most 引号的情况下使用它,以避免在一些异常情况下出现语法错误。


然而,在命令行中有几个问题(让我们在这里坚持第一种方法),我想在这里描述一下:

  • (未知)路径未加引号,这可能会导致某些特殊字符出现问题,因此最好使用 "%path_to_look%"(假设变量本身不包含引号,这是不可取的) ;
  • dir,没有它的 /B 开关,returns 不仅仅是文件名(如 dates/times、文件大小以及页眉和页脚),它您可能并不真正关心,因此提供 /B;
  • dir /A 指定列出所有项目(如文件、目录、重新分析点,甚至隐藏和系统项目),尽管您可能只对(未隐藏和 non-system)文件感兴趣,因此您可能想改用 /A:-D-H-S
  • 文件名也可能包含white-spaces,因此您应该指定for /F选项delims=;文件名理论上也可以以 ; 开头,因此 eol=| 可能有意义(因为 | 不能出现在文件名中);
  • 文件名是case-insensitive,所以应该是在findstr中加上/I的关键字搜索;
  • 您应该使用引用的 set 语法以保护特殊字符;

所有这些导致以下改进的命令行:

for /F "delims= eol=|" %%A in ('dir /B /A:-D-H-S "%path_to_look%" ^| findstr /I "\<mykeyword\>"') do set "res1=%%A"