如何编写一个包含空格的搜索模式以在findstr中使用?

39

我想在特定目录中搜索所有文件,查找类似于以下语句的出现:

  Load frmXYZ

我正在使用Windows 7系统,使用findstr命令。我尝试过:

  findstr /n Load.*frm *.*

但这会给我带来一些不想要的结果,比如:

 If ABCFormLoaded Then Unload frmPQR

所以我尝试在Loadfrm之间加一个空格,并像这样输入命令:

 findstr /n Load frm *.*

但是这只是搜索了所有出现了单词 load 或者所有出现了单词 frm。我该如何解决这个问题?


你不是忘了加上/r选项来启用正则表达式吗? - Joey
它说 /r 使用搜索字符串作为正则表达式。那么这是否意味着“空格”将被视为正则表达式的一部分?让我试试。 - CodeBlue
好的,我尝试了,但是我不确定如何使用它。 - CodeBlue
这段代码有点过时了,但我一般只使用 . 代替空格,因为大多数情况下我关心的是表达式中其他字母的位置,而空格是否真的是空格并不那么重要。findstr /n /r Load.frm *.*(别误会,/c 很有用,但半数时间似乎对我不起作用)。 - ebyrob
4个回答

45

如果您使用空格,您需要使用/C:选项将文本字符串传递给正则表达式/R选项。
一旦到达正则表达式,它就被视为正则表达式。

话虽如此,这是典型的 MS 垃圾。

使用两个正则表达式搜索字符串

关键是您必须使用 2 个字符串来处理以下情况:
Load frm 在开头,如下所示:

  • Load frm apples bananas carrots

或者在中间,如下所示:

  • some other text Load frm and more

没有字符类的版本

以下是使用 XP sp3,Windows 7 可能不同,两者都是垃圾!

findstr /N /R /C:" *Load *frm" /C:"^Load *frm" test.txt

7:Load frm is ok    
8:    Load     frm is ok  

注意冒号

注意:/C:中的冒号是必须的,否则将无法正常工作。

如果省略冒号,则findstr的错误处理方式就是将/C视为无效选项,忽略该无效选项并继续执行。这会导致意外和不必要的输出。

使用字符类的等效版本

findstr /N /R /C:"[ ][ ]*Load[ ][ ]*frm" /C:"^Load[ ][ ]*frm" test.txt

字符类分解

// The first regex search string breaks down like this:
[ ]   // require 1 space
[ ]*  // optional many spaces
Load  // literal 'Load'
[ ]   // require 1 space
[ ]*  // optional many spaces
frm   // literal 'frm'

// The second regex search string breaks down like this:
^     // beginning of line
Load  // literal 'Load'
[ ]   // require 1 space
[ ]*  // optional many spaces
frm   // literal 'frm'

一个真正的正则表达式可能是\bLoad\s+frm

感谢!非常有帮助。好的,"trash" 是什么意思? - CodeBlue
4
哦,我以为那是一个技术术语! - CodeBlue
如果这是垃圾问题,老实说我看不出回答这类问题的意义。除非你是清洁工。 - Neurotransmitter
3
@TranslucentCloud - 即使是垃圾也必须处理。嘿,看那边,那是垃圾:“必须使用2个字符串来处理'Load frm'在开头或中间的情况。” - user557597
似乎字符类在Windows 10上不再起作用了:echo 1.999 K| findstr /R "\....[ ]K" - Thomas Weller

33

使用/c选项:

findstr /n /c:"Load frm" *.*

从帮助文档中获取的内容(findstr /?):

/C:string  Uses specified string as a literal search string.

如果在“Load”和“frm”之间有多个空格,会怎么样? - CodeBlue
1
使用正则表达式,您需要同时使用“/r”来匹配空格。 - Joey
1
我尝试使用 findstr /n /r /c:"Load[]+ frm" 后跟星号点星号进行搜索,但现在它什么也没有显示。 - CodeBlue
Findstr有自己的一套不太好用的正则表达式实现,它不包括“+”作为元字符。 - LinuxDisciple
2
那么就使用 [ ][ ]*。正则表达式不一定需要 + - Joey

9

使用单词分隔符正则表达式

我使用了特殊的\< "单词开头"正则表达式符号。

我在Win10版本的findstr上尝试了这个方法。但据微软称,这个特殊的\<符号从WinXP开始就一直存在于findstr.exe中。

下面详细介绍了许多无法正常工作的选项,非常痛苦。

最底部是真正奏效的方法。

示例文件本身

C:\>type lines.txt
Load frmXYZ                         // This line should match.
If ABCFormLoaded Then Unload frmPQR // This line should NOT match.
pears Load frm grapes pineapples    // This line should match.
                                    // This blank line should NOT match.
LOAD FRMXYZ                         // This line should match.
IF ABCFORMLOADED THEN UNLOAD FRMPQR // This line should NOT match.
PEARS LOAD FRM GRAPES PINEAPPLES    // This line should match.
                                    // This blank line should NOT match.
load frmxyz                         // This line should match.
if abcformloaded then unload frmpqr // This line should NOT match.
pears load frm grapes pineapples    // This line should match.

错误。在常规执行中,空格被视为分隔符。

C:\>type lines.txt | findstr /N "Load frm"
1:Load frmXYZ                         // This line should match.
2:If ABCFormLoaded Then Unload frmPQR // This line should NOT match.
3:pears Load frm grapes pineapples    // This line should match.
9:load frmxyz                         // This line should match.
10:if abcformloaded then unload frmpqr // This line should NOT match.
11:pears load frm grapes pineapples    // This line should match.

错误:使用正则表达式选项时,空格仍被视为分隔符。

C:\>type lines.txt | findstr /N /R "Load frm"
1:Load frmXYZ                         // This line should match.
2:If ABCFormLoaded Then Unload frmPQR // This line should NOT match.
3:pears Load frm grapes pineapples    // This line should match.
9:load frmxyz                         // This line should match.
10:if abcformloaded then unload frmpqr // This line should NOT match.
11:pears load frm grapes pineapples    // This line should match.    

更加正确但仍然错误。使用/C选项我们现在保留了空格,但是无法找到其他字符的情况。

C:\>type lines.txt | findstr /N /R /C:"Load frm"
1:Load frmXYZ                         // This line should match.
3:pears Load frm grapes pineapples    // This line should match.

错误。/i(不区分大小写)并没有帮助。我们得到了我们不想要的单词内部的匹配项。

C:\>type lines.txt | findstr /N /R /I /C:"Load frm"
1:Load frmXYZ                         // This line should match.
2:If ABCFormLoaded Then Unload frmPQR // This line should NOT match.
3:pears Load frm grapes pineapples    // This line should match.
5:LOAD FRMXYZ                         // This line should match.
6:IF ABCFORMLOADED THEN UNLOAD FRMPQR // This line should NOT match.
7:PEARS LOAD FRM GRAPES PINEAPPLES    // This line should match.
9:load frmxyz                         // This line should match.
10:if abcformloaded then unload frmpqr // This line should NOT match.
11:pears load frm grapes pineapples    // This line should match.

正确。使用特殊的“单词开头”正则表达式符号。匹配行首或空格。

不区分大小写:

C:\>type lines.txt | findstr /N /R /C:"\<Load frm"
1:Load frmXYZ                         // This line should match.
3:pears Load frm grapes pineapples    // This line should match.

或忽略大小写

C:\>type lines.txt | findstr /N /R /I /C:"\<Load frm"
1:Load frmXYZ                         // This line should match.
3:pears Load frm grapes pineapples    // This line should match.
5:LOAD FRMXYZ                         // This line should match.
7:PEARS LOAD FRM GRAPES PINEAPPLES    // This line should match.
9:load frmxyz                         // This line should match.
11:pears load frm grapes pineapples    // This line should match.

-1

这段代码只允许关键字中包含字母、数字、下划线和空格:

set /p keyword="Enter keyword: " || Set keyword=

set keyword_replaced=%keyword: =_%

echo %keyword_replaced%| findstr /r "[^0-9a-zA-Z_]" > nul
if errorlevel 1 goto noexit
echo special characters in keyword not allowed (except space and _), TERMINATING
timeout 4
exit /b 0
:noexit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接