1

我正在 Windows 批处理文件中寻找一种方法来查找文件是否包含Shutdown给定次数的单词。

我已经尝试过使用FINDSTR

 FINDSTR /r .*Shutdown.*{5} file.txt

这似乎不起作用,但如果我删除{5}它,它会成功执行。

另外我最终希望5成为一个变量,大概这可以通过某种动态命令来实现?

谢谢

4

3 回答 3

3

可以使用 FINDSTR 检测文件中的任何位置是否出现 5 次或更多次“关机”。您需要的所有信息都包含在Windows FINDSTR 命令有哪些未记录的功能和限制?,但这有点棘手,而且一点也不明显。

正则表达式搜索可以跨多行匹配 Shutdown 的多个实例,只要所有中间字符(包括回车符和换行符)都与适当的字符类范围匹配。我无法在此处发布所需的字符,因此我将在尖括号内使用符号表示法。

以下正则表达式将匹配除 0xFF(十进制 255)以外的任何字节字符。它由一个字符类表达式组成,该表达式具有两个范围和中间的 0xFF 间隙。间隙很关键,因为如果包含 0xFF,FINDSTR 将失败(并且可能挂起):

[<0x01>-<space><tab>-<0xEA>]

您可能认为表达式应该是[<0x01>-<0xFE>],但这不起作用,因为 FINDSTR 不按数字代码值整理字符。

因此,要查找文件中任何位置的 5 个或更多实例Shutdown,您需要以下正则表达式搜索:

Shutdown[<0x01>-<space><tab>-<0xEA>]*Shutdown[<0x01>-<space><tab>-<0xEA>]*Shutdown[<0x01>-<space><tab>-<0xEA>]*Shutdown[<0x01>-<space><tab>-<0xEA>]*Shutdown

0xEA(十进制 234)字符是扩展 ASCII 字符,扩展 ASCII 不能包含在 FINDSTR 搜索的命令行中。所以搜索字符串必须放在外部文件中,并且/G:file必须使用选项。

这是一个完整的批处理脚本,它将要搜索的最小数量的 Shutdown 实例作为第一个参数,并将要搜索的文件的名称作为第二个参数。我再次在尖括号内使用符号表示法来代替所需的实际字符。

@echo off
set count=%1
set file=%2
setlocal enableDelayedExpansion
set "search="
for /l %%N in (1 1 %count%) do set "search=!search!Shutdown[<0x01>-<space><tab>-<0xEA>]*"
set "search=!search:~0,-9!"
echo(!search!>search.txt
findstr /rg:search.txt %file% >nul&&echo FOUND||echo NOT found

支持的最大计数受最大正则表达式字符串长度的限制。对于 XP,最大正则表达式长度为 127 个字节,相当于计数 7。在 Vista 和 Windows 7 上,最大正则表达式长度为 254 个字节,应该支持 15 个字节。但是我在 Windows 7 上的测试只支持最多12. 额外的测试显示最大长度受出现的字符串文字和字符类的数量以及它们的相对位置的影响。但我一直无法弄清楚一个确切的公式。


如果您不想使用外部文件,那么以下正则表达式几乎一样好。它匹配除以下扩展 ASCII 十六进制代码以外的任何字符:0xE0、0xE2、0xE3、0xE4、0xE5、0xE7、0xE8、0xE9、0xEA、0xEB、0xED、0xEE、0xFF。

[<0x01>-<space><tab>-Z]

完整的正则表达式搜索将是:

Shutdown[<0x01>-<space><tab>-Z]*Shutdown[<0x01>-<space><tab>-Z]*Shutdown[<0x01>-<space><tab>-Z]*Shutdown[<0x01>-<space><tab>-Z]*Shutdown

这是完整的批处理脚本:

@echo off
setlocal enableDelayedExpansion
set count=%1
set file=%2
set "search="
for /l %%N in (1 1 %count%) do set "search=!search!Shutdown[<0x01>-<space><tab>-Z]*"
set "search=!search:~0,-9!"
findstr /rc:"!search!" %file% >nul&&echo FOUND||echo NOT found
于 2013-05-19T01:51:01.030 回答
2
.*Shutdown.*Shutdown.*Shutdown.*Shutdown.*Shutdown.*

似乎是唯一的方法FINDSTR

呲牙咧嘴。


测试批次:

@ECHO OFF
SETLOCAL
FOR /f "delims=" %%i IN (f5shutdown.txt) DO (
 ECHO %%i|FINDSTR /r .*Shutdown.*Shutdown.*Shutdown.*Shutdown.*Shutdown.* >NUL
 IF ERRORLEVEL 1 ECHO FAILED IN "%%i"
 IF NOT ERRORLEVEL 1 ECHO FOUND  IN "%%i"
)

GOTO :eof

在 f5shutdown.txt 中测试文本文件

Shutdown
Shutdown Shutdown
Shutdown Shutdown Shutdown Shutdown
Shutdown Shutdown Shutdown Shutdown Shutdown
Shutdown already !Shutdown Shutdown Shutdown Shutdown now
You should now Shutdown Shutdown Shutdown Shutdown Shutdown
ShutdownShutdownShutdownShutdownShutdown
OK, don't shutdown then...

结果:

FAILED IN "Shutdown"
FAILED IN "Shutdown Shutdown"
FAILED IN "Shutdown Shutdown Shutdown Shutdown"
FOUND  IN "Shutdown Shutdown Shutdown Shutdown Shutdown"
FOUND  IN "Shutdown already !Shutdown Shutdown Shutdown Shutdown now"
FOUND  IN "You should now Shutdown Shutdown Shutdown Shutdown Shutdown"
FOUND  IN "ShutdownShutdownShutdownShutdownShutdown"
FAILED IN "OK, don't shutdown then..."

为我工作(W7)


啊-也许您的意思是“出现在 5 行(或其他)上或“在文件中出现 5 次”...

@ECHO OFF
SETLOCAL
FOR /f "delims=" %%i IN (f5shutdown.txt) DO (
 ECHO %%i|FINDSTR /r .*Shutdown.*Shutdown.*Shutdown.*Shutdown.*Shutdown.* >NUL
 IF ERRORLEVEL 1 ECHO FAILED IN "%%i"
 IF NOT ERRORLEVEL 1 ECHO FOUND  IN "%%i"
)

:: For 'shutdown' on n different lines: (assuming case-insensitive)
FOR /f %%i IN ('FIND /i /c "shutdown" ^<f5shutdown.txt') DO SET shutdowns=%%i
ECHO Second method: %shutdowns% lines found with "Shutdown"

:: For 'shutdown' occurrences (assuming case-insensitive)
SET /a shutdowns=0
FOR /f "delims=" %%i IN (f5shutdown.txt) DO (
 SET line=%%i
 CALL :findem
)
ECHO Third method found "Shutdown" %shutdowns% times
GOTO :eof

:findem
SET line=%line:"=%
SET after=%line:*shutdown=%
IF NOT DEFINED after SET /a shutdowns+=1&GOTO :EOF 
if NOT "%line%"=="%after%" SET "line=%after%"&SET /a shutdowns+=1&GOTO findem
GOTO :eof

(我为测试添加了一个额外的不包含关机的行。发现 8 行和 28 次出现)

于 2013-05-17T13:13:20.210 回答
0

这应该检测到何时关闭 file.txt 中只有 5 行

@echo off
for /f %%a in ('find /i /c "shutdown" ^< "file.txt" ') do if %%a EQU 5 echo found it 5 times
于 2013-05-17T20:04:07.960 回答