2013-05-17 3 views
1

Я ищу способ в пакетном файле Windows, чтобы найти, содержит ли файл слово Shutdown определенное количество раз.Несколько экземпляров строки RegEx в FINDSTR

Я попытался это с помощью FINDSTR:

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

Это не похоже на работу, но если я удалю {5} он выполняет успешно.

Также мне бы хотелось, чтобы 5 был переменной, предположительно это возможно с помощью какой-либо динамической команды?

Благодаря

ответ

2
.*Shutdown.*Shutdown.*Shutdown.*Shutdown.*Shutdown.* 

, казалось бы, единственный способ для FINDSTR

srsly.


испытания партии:

@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 вхождений)

+0

OMG RLY? Хорошо, поэтому, если бы я хотел переменное число '. * Shutdown. *' 'S, мне нужно было бы цитировать 'вокруг [и вокруг] {x}'? – Arj

+0

Вы получили его в одном. Как обычно - half-er, -BAKED-реализация .... – Magoo

+0

Я только что попробовал свой код и, похоже, не вернул правильный результат .. он не находит строку – Arj

0

Это должно определить, когда завершение работы только на 5 строк в file.txt

@echo off 
for /f %%a in ('find /i /c "shutdown" ^< "file.txt" ') do if %%a EQU 5 echo found it 5 times 
+0

Это будет определять, содержит ли файл не менее 5 строк с SHUTDOWN, но он не будет правильно подсчитывать количество SHUTDOWN, если некоторые из них отображаются в одной строке. Это может быть или не быть проблемой для ОП. – dbenham

+0

В моем конкретном случае это было бы хорошо, но в целом идеальное решение дало бы вам общее количество или, возможно, вариант включения/исключения нескольких экземпляров в одной строке. – Arj

2

можно использовать Findstr, чтобы обнаружить, если «Shutdown» появится 5 или более раз в любом месте файла. Вся информация, которая вам нужна, содержится в пределах What are the undocumented features and limitations of the Windows FINDSTR command?, но это более чем сложно, и совсем не очевидно.

Поиск в регулярном выражении может соответствовать нескольким экземплярам Shutdown по нескольким строкам, если все промежуточные символы, включая символы возврата каретки и строки, соответствуют соответствующему диапазону классов символов. Я не могу публиковать персонажи, необходимые здесь, поэтому я буду использовать символическую нотацию в угловых скобках.

Следующее выражение регулярного выражения будет соответствовать любому байтовому символу, кроме 0xFF (decimal 255). Он состоит из выражения класса символов с двумя диапазонами и промежутком в середине для 0xFF. Зазор имеет решающее значение, потому что FINDSTR потерпит неудачу (и, возможно, зависнуть), если 0xFF входит:

[<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 
+0

EDIT - Исправлено ненужное выражение из конца строки поиска, чтобы максимизировать поддерживаемое значение счетчика. Также исправлено обсуждение ограничения количества. Также добавлено объяснение нечетного секвенирования в выражении диапазона классов символов. – dbenham

+0

Невероятный, какой подробный ответ. Спасибо – Arj

+0

В моем случае я получаю сообщение о том, что выражение поиска слишком длинное, но, без сомнения, пример кода будет очень полезен. благодаря – Arj

Смежные вопросы