Как написать шаблон поиска, чтобы включить пробел в findstr? - PullRequest
30 голосов
/ 20 марта 2012

Я хочу найти во всех файлах в определенном каталоге вхождения таких утверждений, как

  Load frmXYZ

Я нахожусь в Windows 7, используя команду findstr.Я попытался:

  findstr /n Load.*frm *.*

Но это дает мне нежелательные результаты, такие как:

 If ABCFormLoaded Then Unload frmPQR

Поэтому я попытался поместить пробел между Load и frm и дал команду, какthis:

 findstr /n Load frm *.*

Но при этом просто ищутся все вхождения слова load или все вхождения слова frm.Как мне обойти эту проблему?

Ответы [ 4 ]

28 голосов
/ 20 марта 2012

Если вы используете пробелы, вам нужна опция /C:, чтобы передать литеральную строку (и) опции регулярного выражения /R.
Как только она попадает в регулярное выражение, она обрабатывается как регулярное выражение.

Тем не менее, это типичный мусор MS.

Используйте две строки поиска регулярных выражений

Суть в том, что вам нужно использовать 2 строки для обработки случаев, когда
Load frm находится в начале примерно так:

  • Load frm apples bananas carrots

ИЛИ в середине примерно так:

  • some other text Load frm and more.

Версия без классов символов

Ниже используется XP sp3, окна 7 могут отличаться, оба являются мусором!

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

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

Mind the Colon

ПРИМЕЧАНИЕ: Двоеточие в /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

23 голосов
/ 20 марта 2012

Используйте параметр /c:

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

Из справки (findstr /?):

/C:string  Uses specified string as a literal search string.
3 голосов
/ 01 марта 2017

Использовать разделитель слов regex

Я использовал специальный символ регулярного выражения \< "начало слова".

Я пробовал это в версии findstr для Win10.Но, согласно Microsoft, этот специальный символ \< был в findstr.exe с тех пор, как WinXP .

Полный (и болезненный) отказ многих опций, которые НЕ работают ниже.

В самом низу: что на самом деле работает.

Сам файл примера

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.

Неправильно: с опцией Regex STILL рассматривается как разделитель.

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.

Неверно./ Я за "Игнорировать дело" не помогает.Мы получаем совпадения из слов, которые нам не нужны.

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.
0 голосов
/ 30 апреля 2015

Этот фрагмент кода допускает только буквы, цифры, подчеркивание и пробелы в ключевом слове:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...