Каковы недокументированные функции и ограничения команды Windows FINDSTR?

команда Windows FINDSTR ужасно документирована. Существует очень простая справка командной строки, доступная через FINDSTR /? или HELP FINDSTR, но это крайне недостаточно. Есть немного больше документации в интернете на https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/findstr.

существует множество функций и ограничений FINDSTR, на которые даже не намекают в документации. Их нельзя было предвидеть без предварительного знания. и / или тщательные эксперименты.

Итак, вопрос в том -каковы недокументированные функции и ограничения FINDSTR?

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

A) разработчики могут в полной мере использовать возможности, которые есть.

B) разработчики не тратят свое время, задаваясь вопросом, почему что-то не работает, когда кажется, что это должен.

пожалуйста, убедитесь, что вы знаете существующую документацию, прежде чем ответить. Если информация покрывается справкой, то она не принадлежит здесь.

Это также не место, чтобы показать интересное использование FINDSTR. Если логический человек мог предвидеть поведение конкретного использования FINDSTR на основе документации, то он не принадлежит здесь.

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

6 ответов


предисловие
большая часть информации в этом ответе была собрана на основе экспериментов, выполненных на машине Vista. Если явно не указано иное, я не подтвердил, относится ли эта информация к другим версиям Windows.

выход FINDSTR
Документация никогда не утруждает себя объяснением вывода FINDSTR. Он ссылается на то, что соответствующие строки печатаются, но ничего больше.

формат вывода соответствующей строки выглядит следующим образом:

имя файла: lineNumber:lineOffset: text

здесь

имя файла: = имя файла, содержащего соответствующую строку. Имя файла не печатается, если запрос был явно для одного файла, или при поиске по конвейеру ввода или перенаправленного ввода. При печати имя файла будет всегда включить любой информации путь. Дополнительная информация о пути будет добавлена, если это. Напечатанный путь всегда относительно предоставленного пути или относительно текущего каталога, если он не указан.

Примечание - префикс имени файла можно избежать при поиске нескольких файлов с помощью нестандартные (и плохо документированные) подстановочные знаки < и >. Точные правила работы этих подстановочных знаков можно найти здесь. Наконец, вы можете посмотреть на это пример того, как нестандартные подстановочные знаки работают с FINDSTR.

номер строки: = номер строки совпадающей строки, представленной в виде десятичного значения с 1, представляющим 1-ю строку ввода. Только печатается, если есть.

lineOffset: = десятичное байтовое смещение начала соответствующая строка, с 0, представляющим 1-й символ 1-й строки. Только печатается, если /O опция указана. Это не смещение совпадения в пределах линии. Это количество байтов от начала файла до начала линии.

текст = двоичное представление соответствующей строки, включая любые &LT;CR> и/или &LT; LF>. Из двоичного вывода ничего не остается, так что этот пример то, что соответствует всем строкам, создаст точную двоичную копию исходного файла.

FINDSTR "^" FILE >FILE_COPY

большинство символов управления и многие расширенные символы ASCII отображаются в виде точек на XP
FINDSTR на XP отображает большинство непечатаемых управляющих символов из соответствующих строк в виде точек (периодов) на экране. Исключения составляют следующие управляющие символы: 0x09 Tab, 0x0A LineFeed, 0x0b Vertical Tab, 0x0c Form Feed, 0x0D Carriage Возвращаться.

XP FINDSTR также преобразует ряд расширенных символов ASCII в точки. Расширенные символы ASCII, отображаемые в XP в виде точек, совпадают с теми, которые преобразуются в командной строке. Вижу "ограничения символов для параметров командной строки-расширенное преобразование ASCII" раздел, позже в этом посте

управляющие символы и расширенный ASCII не преобразуются в точки на XP, если вывод передается по конвейеру, перенаправляется в файл или в предложение FOR IN ().

Vista и Windows 7 всегда отображают все символы как себя, а не как точки.

коды возврата (уровень ошибок)

  • 0 (успех)
    • матч был найден по крайней мере в одной строке по крайней мере одного файла.
  • 1 (отказ)
    • не найдено совпадений ни в одной строке файл.
    • недопустимый цвет, указанный /A:xx опции
  • 2 (ошибка)
    • несовместимые параметры /L и /R как указано
    • отсутствует аргумент после /A:, /F:, /C:, /D: или /G:
    • на /F:file или /G:file не нашел
  • 255 (ошибка)
  • источник данных для поиска (обновлено на основе тестов с Windows 7)
    Findstr может искать данные только из одного из следующих источников:

    • имена файлов, указанных в качестве аргументов и/или с помощью /F:file выбор.

    • stdin через перенаправление findstr "searchString" <file

    • поток данных из трубы type file | findstr "searchString"

    Аргументы / параметры имеют приоритет над перенаправлением,которое имеет приоритет над переданными данными.

    аргументы имени файла и /F:file могут быть объединены. Можно использовать несколько аргументов имени файла. Если несколько /F:file параметры заданы, тогда только последний. Дикие карты разрешено в аргументах имени файла, но не в файле, на который указывает /F:file.

    источник строк поиска (обновлено на основе тестов с Windows 7)
    The /G:file и /C:string опции могут быть объединены. Несколько /C:string опции могут быть указаны. Если несколько /G:file параметры заданы, тогда только последний. Если любой /G:file или /C:string используется, то все аргументы не-option считаются файлами для поиска. Если ни /G:file, ни /C:string используется, то первый аргумент non-option рассматривается как список разделенных пробелами поисковых терминов.

    имена файлов не должны цитироваться в файле при использовании .
    Имена файлов могут содержать пробелы и другие специальные символы. Большинство команд требуют, чтобы такие имена файлов указаны. Но находка!-Вариант -42--> требует, чтобы имена файлов в архиве.txt не должен цитироваться. Файл не будет найден если имя указано.

    ошибка-короткие 8.3 имена файлов могут сломать /D и /S опции
    Как и во всех командах Windows, FINDSTR попытается сопоставить длинное имя и короткое имя 8.3 при поиске файлов для поиска. Предположим, что текущая папка содержит следующие непустые файлы:

    b1.txt
    b.txt2
    c.txt
    

    следующая команда успешно найдет все 3 файла:

    findstr /m "^" *.txt
    

    b.txt2 матчи, потому что соответствующее короткое имя B9F64~1.TXT матчи. Это согласуется с поведением всех других команд Windows.

    но ошибка с /D и /S options заставляет следующие команды находить только b1.txt

    findstr /m /d:. "^" *.txt
    findstr /m /s "^" *.txt
    

    ошибка мешает b.txt2 от нахождения, а также все имена файлов, которые сортируются после b.txt2 в том же каталоге. Дополнительные файлы, которые сортируются раньше, например a.txt, находится. Дополнительные файлы, которые сортируются позже, например d.txt, пропустили после того, как ошибка была вызвана.

    каждый искомый каталог обрабатывается независимо. Например,/S опция успешно начнет поиск в дочерней папке после того, как не удалось найти файлы в Родительском, но как только ошибка вызывает короткое имя файла, чтобы быть пропущенным в дочернем, то все последующие файлы в этой дочерней папке также будут пропущены.

    команды работают без ошибок, если на компьютере с одинаковыми именами файлов NTFS 8.3 генерация имен отключена. Конечно!--45--> не будет найдено, но c.txt будет найден должным образом.

    не все короткие имена вызывают ошибку. Все случаи прослушиваемого поведения, которые я видел, включают расширение длиной более 3 символов с коротким именем 8.3, которое начинается так же, как обычное имя, которое не требует имени 8.3.

    ошибка была подтверждена на XP, Vista и Windows 7.

    непечатаемые символы и /P опции
    The /P опция заставляет FINDSTR пропустить любой файл, содержащий любой из следующих десятичных байтовых кодов:
    0-7, 14-25, 27-31.

    иными словами,/P опция будет пропускать только файлы, содержащие непечатаемые управляющие символы. Управляющие символы-это коды, меньшие или равные 31 (0x1F). FINDSTR обрабатывает следующие управляющие символы как печатаемые:

     8  0x08  backspace
     9  0x09  horizontal tab
    10  0x0A  line feed
    11  0x0B  vertical tab
    12  0x0C  form feed
    13  0x0D  carriage return
    26  0x1A  substitute (end of text)
    

    все другие контрольные символы рассматривается как непечатаемый, наличие которого вызывает /P возможность пропустить файл.

    Piped и Перенаправленный вход может иметь <CR><LF> добавлен
    Если входной сигнал передается по конвейеру и последний символ потока не <LF>, затем FINDSTR автоматически добавит <CR><LF> на вход. Это было подтверждено на XP, Vista и Windows 7. (раньше я думал, что труба Windows отвечает за изменение ввода, но у меня есть с тех пор обнаружил, что FINDSTR фактически делает модификацию.)

    то же самое верно для перенаправленного ввода на Vista. Если последний символ файла, используемого в качестве перенаправленного ввода, не <LF>, затем FINDSTR автоматически добавит <CR><LF> на вход. Однако XP и Windows 7 не изменяют перенаправленный ввод.

    FINDSTR зависает на XP и Windows 7, Если перенаправленный ввод не заканчивается на <LF>
    Это противно "функция" на XP и Windows 7. Если последний символ файла, используемого в качестве перенаправленного ввода, не заканчивается на <LF>, затем FINDSTR будет висеть бесконечно, как только он достигнет конца перенаправленного файла.

    последняя строка передаваемых данных может быть проигнорирована, если она состоит из одного символа
    Если входной трубопровод, и последняя строка состоит из одного символа, за которым не следует <LF>, затем FINDSTR полностью игнорирует последний линия.

    пример-первая команда с одним символом и no <LF> не соответствует, но вторая команда с 2 символами работает нормально, как и третья команда, которая имеет один символ с завершением новой строки.

    > set /p "=x" <nul | findstr "^"
    
    > set /p "=xx" <nul | findstr "^"
    xx
    
    > echo x| findstr "^"
    x
    

    сообщает пользователь DosTips Sponge Belly at новая ошибка findstr. Подтверждено на XP, Windows 7 и Windows 8. Еще не слышал о Vista. (У меня больше нет Vista для теста).

    синтаксис
    Опции могут быть с префиксом либо / или - Опции могут быть объединены после одного / или -. Однако объединенный список параметров может содержать не более одного параметра с несколькими характеристиками, например OFF или F:, и этот параметр должен быть последним в списке.

    ниже приведены эквивалентные способы выражения поиска regex без учета регистра для любой строки, содержащей как "hello", так и "goodbye" в любом заказ

    • /i /r /c:"hello.*goodbye" /c:"goodbye.*hello"

    • -i -r -c:"hello.*goodbye" /c:"goodbye.*hello"

    • /irc:"hello.*goodbye" /c:"goodbye.*hello"

    ограничения длины строки поиска
    В Vista максимально допустимая длина для одной строки поиска составляет 511 байт. Если какая-либо строка поиска превышает 511, то результатом является FINDSTR: Search string too long. ошибка с ERRORLEVEL 2.

    при выполнении поиска регулярных выражений максимальная длина строки поиска-254. Регулярное выражение с длиной между 255 и 511 приведет в FINDSTR: Out of memory ошибка с ERRORLEVEL 2. Регулярное выражение length >511 приводит к FINDSTR: Search string too long. ошибка.

    в Windows XP длина строки поиска, по-видимому, короче. ошибка Findstr: "строка поиска слишком длинная": как извлечь и сопоставить подстроку в цикле" for"? Предельный XP составляет 127 байт прямом и regex поиски.

    ограничения на длину строки
    Файлы, заданные в качестве аргумента командной строки или с помощью параметра /F:FILE, не имеют ограничения длины строки. Поиски были успешно выполнены для файла 128 МБ, который не содержит ни одного .

    переданные данные и Перенаправленный ввод ограничены 8191 байтом на строку. Этот предел является "особенностью" FINDSTR. Это не присуще трубам или перенаправлению. FINDSTR с использованием перенаправленного stdin или конвейерного ввода никогда не будет соответствует любой строке >=8K байт. Строки >= 8k генерируют сообщение об ошибке в stderr, но ERRORLEVEL по-прежнему равен 0, если строка поиска найдена хотя бы в одной строке хотя бы одного файла.

    тип поиска по умолчанию: литерал vs регулярное выражение
    /C:"string" - по умолчанию используется литерал /L. Явное объединение параметра /L с параметром /C:" string", безусловно, работает, но является избыточным.

    "string argument" - значение по умолчанию зависит от содержания первого строка поиска. (помните, что используется для разграничения строк поиска.) если первая строка поиска является допустимым регулярным выражением, содержащим по крайней мере один не-экранированный мета-символ, то все строки поиска рассматриваются как регулярные выражения. В противном случае все строки поиска рассматриваются как литералы. Например, "51.4 200" будет рассматриваться как два регулярных выражения, потому что первая строка содержит не-экранированную точку, тогда как "200 51.4" будет рассматриваться как два литерала, потому что первая строка не содержит мета-символы.

    /G:file - значение по умолчанию зависит от содержимого первой непустой строки в файле. Если первая строка поиска является допустимым регулярным выражением, содержащим по крайней мере один метасимвол без экранирования, то все строки поиска рассматриваются как регулярные выражения. В противном случае все строки поиска рассматриваются как литералы.

    рекомендация - всегда явно указывать /L буквальный вариант или /R опция регулярного выражения при использовании "string argument" или /G:file.

    ошибка-указание нескольких буквальных строк поиска может дать ненадежные результаты

    в следующем простом примере FINDSTR не удается найти совпадение, даже если оно должно.

    echo ffffaaa|findstr /l "ffffaaa faffaffddd"
    

    эта ошибка была подтверждена в Windows Server 2003, Windows XP, Vista и Windows 7.

    основываясь на экспериментах, FINDSTR может потерпеть неудачу, если все выполняются следующие условия:

    • поиск использует несколько буквальных строк поиска
    • строки поиска имеют разную длину
    • короткая строка поиска имеет некоторое перекрытие с более длинной строкой поиска
    • поиск чувствителен к регистру (нет )

    в каждой неудаче, которую я видел, это всегда одна из более коротких строк поиска, которая терпит неудачу.

    для Подробнее см. почему этот пример FINDSTR с несколькими строками поиска литералов не находит совпадения?

    цитаты и backslahses в аргументы командной строки - Примечание:
    Информация в этом выделенном разделе не является 100% точной. После того, как я написал этот раздел, пользователь MC ND указал мне на ссылка это документы, как библиотека Microsoft C/C++ анализирует параметры. Он это ужасно сложно, но, похоже, точно предсказать правила обратной косой черты и кавычки для аргументов командной строки FINDSTR. Я рекомендуется использовать выделенную ниже информацию в качестве руководства, но если вы хотите получить более точную информацию, обратитесь к ссылке.

    экранирование цитаты в строке поиска командной строки
    кавычки в строке поиска командной строки должны быть экранированы с обратной косой чертой, как \". Это касается как буквальное и regex строка поиска. Этот информация была подтверждена на XP, Vista и Windows 7.

    Примечание: цитата также может потребоваться экранировать для CMD.EXE парсер, но это не имеет ничего общего с FINDSTR. Например, для поиска одиночная цитата Вы смогли использовать:

    FINDSTR \^" file && echo found || echo not found

    экранирование обратной косой черты в строках поиска командной строки
    обратная косая черта в строке поиска литерала может нормально быть представлен как \ или \. Они, как правило, равнозначны. (могут быть необычные случаи в Vista, где обратная косая черта всегда должна быть экранирована, но я нет уже есть машина Vista для теста).

    но есть некоторые особые случаи:

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

    • \ может быть квалифицировано как \\ или \\
    • \\ может быть квалифицировано как \\\ или \\\

    поиск одной или нескольких обратных косых черт перед цитатой является странным. Логика предположим, что цитата должна быть экранирована, и каждый из ведущих обратные косые черты нужно было бы избежать, но это не работает! Вместо, каждая из ведущих обратных косых черт должна быть дважды экранирована, а цитата убежал обычно:

    • \" должно быть закодировано как \\\"
    • \" должно быть закодировано как \\\\\"

    как уже отмечалось ранее, одна или несколько экранированных кавычек также могут потребовать экранирования с ^ для анализатора CMD

    информация в этом разделе была подтверждена на XP и Windows 7.

    экранирование обратной косой черты в командной строке regex search струны

    • Vista только: слеш в regex должен быть либо двойным преобразованием как \\, или еще один экранированный в наборе классов символов, например [\]

    • XP и Windows 7: слеш в regex всегда может быть представлен как [\]. Обычно его можно представить как \. Но это не работает, если обратная косая черта предшествует беглый цитата.

      одна или несколько обратных косых черт перед экранированной цитатой должны быть двойной сбежал, или закодирован как [\]

      • \" может быть квалифицировано как \\\" или [\]\"
      • \" может быть квалифицировано как \\\\\" или [\][\]\" или \[\]\"

    экранирование кавычки и обратной косой черты в / G: строки поиска файлов
    Отдельные цитаты и обратные косые черты в файле строки поиска, заданном параметром /G: file, не нужно экранировать, но они могут быть.

    " и \" эквивалентны.

    \ и \ эквивалентны.

    если цель состоит в том, чтобы найти \\, то, по крайней мере, ведущая обратная косая черта должна быть экранирована. Оба!--95--> и \\ работа.

    если намерение состоит в том, чтобы найти\", то, по крайней мере, ведущая обратная косая черта должна быть экранирована. Оба!--102--> и \\" работа.

    экранирование цитаты и обратной косой черты в / G:строки поиска регулярных выражений файла
    Это тот случай, когда escape-последовательности работают так, как ожидалось, на основе документации. Цитата не является метасимволом regex, поэтому ее не нужно экранировать (но можно). Обратная косая черта-это метасимвол regex, поэтому он должен быть экранирован.

    ограничения символов для параметров командной строки-расширенное преобразование ASCII
    Значение null символ (0x00) не может отображаться ни в одной строке командной строки. Любой другой однобайтовый символ может появиться в строке (0x01-0xFF). Однако FINDSTR преобразует многие расширенные символы ASCII, которые он находит в параметрах командной строки, в другие символы. Это имеет большое влияние в двух направлениях:

    1) Многие расширенные символы ASCII не будут совпадать, если они используются в качестве строки поиска в командной строке. Это ограничение одинаково для поиска литералов и регулярных выражений. Если поиск строка должна содержать расширенный ASCII, затем /G:FILE вместо этого следует использовать опцию.

    2) FINDSTR может не найти файл, если имя содержит расширенные символы ASCII и имя файла указано в командной строке. Если файл для поиска содержит расширенный ASCII в имени, то /F:FILE вместо этого следует использовать опцию.

    вот полный список расширенных преобразований символов ASCII, которые FINDSTR выполняет в строках командной строки. Каждый символ представлен в виде десятичного байтового значения кода. Первый код представляет символ, указанный в командной строке, а второй код представляет символ, в который он преобразуется. Примечание - этот список был составлен на американские машины. Я не знаю, какое влияние могут оказать другие языки в этом списке.

    158 treated as 080     199 treated as 221     226 treated as 071
    169 treated as 170     200 treated as 043     227 treated as 112
    176 treated as 221     201 treated as 043     228 treated as 083
    177 treated as 221     202 treated as 045     229 treated as 115
    178 treated as 221     203 treated as 045     231 treated as 116
    179 treated as 221     204 treated as 221     232 treated as 070
    180 treated as 221     205 treated as 045     233 treated as 084
    181 treated as 221     206 treated as 043     234 treated as 079
    182 treated as 221     207 treated as 045     235 treated as 100
    183 treated as 043     208 treated as 045     236 treated as 056
    184 treated as 043     209 treated as 045     237 treated as 102
    185 treated as 221     210 treated as 045     238 treated as 101
    186 treated as 221     211 treated as 043     239 treated as 110
    187 treated as 043     212 treated as 043     240 treated as 061
    188 treated as 043     213 treated as 043     242 treated as 061
    189 treated as 043     214 treated as 043     243 treated as 061
    190 treated as 043     215 treated as 043     244 treated as 040
    191 treated as 043     216 treated as 043     245 treated as 041
    192 treated as 043     217 treated as 043     247 treated as 126
    193 treated as 045     218 treated as 043     249 treated as 250
    194 treated as 045     219 treated as 221     251 treated as 118
    195 treated as 043     220 treated as 095     252 treated as 110
    196 treated as 045     222 treated as 221     254 treated as 221
    197 treated as 043     223 treated as 095
    198 treated as 221     224 treated as 097
    

    любой символ >0 не в списке выше рассматривается как сам, в том числе <CR> и LF>. Самый простой способ включить odd символы <CR> и <LF> - это получить их в переменную среды и использовать отложенное расширение в аргументе командной строки.

    ограничения символов для строк, найденных в файлах, указанных в /G:FILE и / F:FILE options
    Символ nul (0x00) может отображаться в файле, но он функционирует как Терминатор строки C. Любые символы после символа nul обрабатываются как другая строка, как если бы они были на другом линия.

    на <CR> и <LF> символы рассматриваются как терминаторы строк, которые завершают строку и не включаются в строку.

    все остальные однобайтовые символы прекрасно включены в строку.

    Поиск файлов Unicode
    FINDSTR не может правильно искать большинство Unicode (UTF-16, UTF-16LE, UTF-16BE, UTF-32), потому что он не может искать байты nul и Unicode обычно содержит много байтов nul.

    однако команда TYPE преобразует UTF-16LE с BOM в однобайтовый набор символов, поэтому команда, подобная следующей, будет работать с UTF-16LE с BOM.

    type unicode.txt|findstr "search"
    

    обратите внимание, что кодовые точки Unicode, которые не поддерживаются активной кодовой страницей, будут преобразованы в ? символы.

    возможно искать UTF-8 покуда ваш поиск строка содержит только ASCII. Однако консольный вывод любых многобайтовых символов UTF-8 будет неправильным. Но если вы перенаправите вывод в файл, то результат будет правильно закодирован UTF-8. Обратите внимание, что если файл UTF-8 содержит спецификацию, то спецификация будет рассматриваться как часть первой строки, которая может сбросить поиск, соответствующий началу строки.

    можно искать многобайтовые символы UTF-8, Если вы поместите строку поиска в файле поиска в кодировке UTF-8 (без спецификации) и используйте параметр /G.

    Конец Строки
    FINDSTR разрывает строки сразу после каждого . Наличие или отсутствие не влияет на разрывы линий.

    поиск через разрывы строк
    Как и ожидалось,. метасимвол regex не будет соответствовать или . Но можно искать через разрыв строки, используя строку поиска командной строки. Символы и должны быть явно сопоставлены. Если найдено многострочное совпадение, печатается только 1-я строка совпадения. FINDSTR затем удваивается до 2-й строки в источнике и начинает поиск снова и снова - своего рода функция типа "смотреть вперед".

    предположим текста.TXT имеет это содержимое (может быть Unix или Windows style)

    A
    A
    A
    B
    A
    A
    

    этот скрипт

    @echo off
    setlocal
    ::Define LF variable containing a linefeed (0x0A)
    set LF=^
    
    
    ::Above 2 blank lines are critical - do not remove
    
    ::Define CR variable containing a carriage return (0x0D)
    for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
    
    setlocal enableDelayedExpansion
    ::regex "!CR!*!LF!" will match both Unix and Windows style End-Of-Line
    findstr /n /r /c:"A!CR!*!LF!A" TEST.TXT
    

    дает эти результаты

    1:A
    2:A
    5:A
    

    поиск по разрывам строк с помощью параметра /G:FILE неточен, потому что единственный способ сопоставить или - это выражение диапазона символов regex, которое бутербродирует символы EOL.

    • [<TAB>-<0x0B>] соответствует , но он также соответствует и

    • [<0x0C>-!] соответствует , но он также соответствует и !

      Примечание-выше являются символическими представления потока байтов regex, так как я не могу графически представлять символы.

    ответ продолжен в части 2 ниже...


    ответ продолжен из части 1 выше - я столкнулся с ограничением ответа на 30 000 символов: - (

    поддержка ограниченных регулярных выражений (regex)
    Поддержка регулярных выражений findstr крайне ограничена. Если его нет в справочной документации, он не поддерживается.

    кроме того, поддерживаемые выражения регулярных выражений реализуются совершенно нестандартным образом, так что результаты могут быть другим, тогда можно было бы ожидать от чего-то вроде grep или perl.

    якоря позиции регулярных выражений ^ и $
    ^ соответствует началу входного потока, а также любой позиции сразу после . Поскольку FINDSTR также разбивает строки после , простое регулярное выражение " ^ " всегда будет соответствовать всем строкам в файле, даже двоичному файлу.

    $ соответствует любой позиции, непосредственно предшествующей &LT; CR>. Это означает, что поиск regex строка, содержащая $ никогда не будет соответствовать строкам в текстовом файле стиля Unix и не будет соответствовать последней строке текстового файла Windows, если отсутствует маркер EOL .

    Примечание - как уже обсуждалось ранее, конвейерный и перенаправленный вход в FINDSTR может иметь <CR><LF> добавлено, что не находится в источнике. Очевидно, это может повлиять на поиск регулярных выражений, который использует $.

    любая строка поиска с символов перед ^ или после $ будет всегда не удается найти совпадение.

    Позиционные Опции /B /E / X
    Позиционные параметры работают так же, как ^ и $, за исключением того, что они также работают для буквальных строк поиска.

    / B функционирует так же, как ^ в начале строки поиска регулярных выражений.

    / e функционирует так же, как $ в конце строки поиска регулярных выражений.

    / X функционирует так же, как иметь оба ^ в начале и $ at конец строки поиска regex.

    регулярное выражение границе слова
    \< должен быть самым первым термином в регулярном выражении. Регулярное выражение не будет соответствовать чему-либо, если ему предшествуют какие-либо другие символы. \< соответствует либо самого начала ввод, в начале строки (позиции сразу после ), или должность сразу же после любого "не-слово" характер. Следующий символ не обязательно должен быть символом "слова".

    \> должно быть, последний срок в регулярном выражении. Регулярное выражение не будет соответствовать чему-либо, если за ним следуют другие символы. \> соответствует либо концу ввода, либо позиции непосредственно перед , либо позиции, непосредственно предшествующей любому символу "не-слова". Предшествующий символ не обязательно должен быть символом "слова".

    вот полный список" не-слов " символов, представленных в виде десятичного байтового кода. Примечание - этот список был составлен на американские машины. Я не знайте, какое влияние другие языки могут иметь в этом списке.

    001   028   063   179   204   230
    002   029   064   180   205   231
    003   030   091   181   206   232
    004   031   092   182   207   233
    005   032   093   183   208   234
    006   033   094   184   209   235
    007   034   096   185   210   236
    008   035   123   186   211   237
    009   036   124   187   212   238
    011   037   125   188   213   239
    012   038   126   189   214   240
    014   039   127   190   215   241
    015   040   155   191   216   242
    016   041   156   192   217   243
    017   042   157   193   218   244
    018   043   158   194   219   245
    019   044   168   195   220   246
    020   045   169   196   221   247
    021   046   170   197   222   248
    022   047   173   198   223   249
    023   058   174   199   224   250
    024   059   175   200   226   251
    025   060   176   201   227   254
    026   061   177   202   228   255
    027   062   178   203   229
    

    диапазоны классов символов регулярных выражений [x-y]
    Диапазоны классов символов работают не так, как ожидалось. См. этот вопрос:почему findstr не обрабатывает случай должным образом (в некоторых обстоятельствах)? вместе с этим ответом: https://stackoverflow.com/a/8767815/1012053.

    проблема в том, что FINDSTR не сопоставляет символы по их значению байтового кода (обычно считается кодом ASCII, но ASCII определяется только из 0x00 - 0x7F). Большинство реализаций регулярных выражений будут рассматривать [A-Z] как все заглавные буквы верхнего регистра. Но FINDSTR использует последовательность сортировки, которая примерно соответствует тому, как работает сортировка. Таким образом, [A-Z] включает полный английский алфавит, как верхний, так и нижний регистр (за исключением "a"), а также неанглийские Альфа-символы с диакритиками.

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

    001
    002
    003
    004
    005
    006
    007
    008
    014
    015
    016
    017
    018           
    019
    020
    021
    022
    023
    024
    025
    026
    027
    028
    029
    030
    031
    127
    039
    045
    032
    255
    009
    010
    011
    012
    013
    033
    034
    035
    036
    037
    038
    040
    041
    042
    044
    046
    047
    058
    059
    063
    064
    091
    092
    093
    094
    095
    096
    123
    124
    125
    126
    173
    168
    155
    156
    157
    158
    043
    249
    060
    061
    062
    241
    174
    175
    246
    251
    239
    247
    240
    243
    242
    169
    244
    245
    254
    196
    205
    179
    186
    218
    213
    214
    201
    191
    184
    183
    187
    192
    212
    211
    200
    217
    190
    189
    188
    195
    198
    199
    204
    180
    181
    182
    185
    194
    209
    210
    203
    193
    207
    208
    202
    197
    216
    215
    206
    223
    220
    221
    222
    219
    176
    177
    178
    170
    248
    230
    250
    048
    172
    171
    049
    050
    253
    051
    052
    053
    054
    055
    056
    057
    236
    097
    065
    166
    160
    133
    131
    132
    142
    134
    143
    145
    146
    098
    066
    099
    067
    135
    128
    100
    068
    101
    069
    130
    144
    138
    136
    137
    102
    070
    159
    103
    071
    104
    072
    105
    073
    161
    141
    140
    139
    106
    074
    107
    075
    108
    076
    109
    077
    110
    252
    078
    164
    165
    111
    079
    167
    162
    149
    147
    148
    153
    112
    080
    113
    081
    114
    082
    115
    083
    225
    116
    084
    117
    085
    163
    151
    150
    129
    154
    118
    086
    119
    087
    120
    088
    121
    089
    152
    122
    090
    224
    226
    235
    238
    233
    227
    229
    228
    231
    237
    232
    234
    

    Regex класс символов срок ограничения и ошибка
    Не только быть FINDSTR ограничен максимум 15 символьными терминами класса в регулярном выражении, он не может должным образом обработать попытку превысить предел. Использование 16 или более терминов класса символов приводит к появлению интерактивного окна с указанием " утилита поиска строки (QGREP) столкнулась с проблемой и должна быть закрыта. Приносим извинения за причиненные неудобства." текст сообщения зависит от версии Windows. Вот один пример FINDSTR, который будет fail:

    echo 01234567890123456|findstr [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
    

    об этой ошибке сообщил пользователь DosTips Judago здесь. Это было подтверждено на XP, Vista и Windows 7.

    Поиск регулярных выражений не выполняется (и может висеть бесконечно), если они включают байтовый код 0xFF (decimal 255)
    Любой поиск регулярных выражений, включающий байтовый код 0xFF (decimal 255), завершится ошибкой. Он терпит неудачу, если байтовый код 0xFF включен напрямую или неявно включен в диапазон классов символов. Помнить это Диапазоны классов символов FINDSTR не сопоставляют символы на основе значения байтового кода. Характер <0xFF> появляется относительно рано в последовательности сортировки между <space> и <tab> символы. Таким образом, любой диапазон классов символов, который включает оба <space> и <tab> не удастся.

    точное поведение немного меняется в зависимости от версии Windows. Windows 7 зависает бесконечно, если включен 0xFF. XP не зависает, но он всегда не может найти совпадение, и иногда выводит следующее сообщение об ошибке - " процесс пытался писать в несуществующую трубу."

    у меня больше нет доступа к машине Vista, поэтому я не смог протестировать Vista.

    ошибка выражения: . и [^anySet] может соответствовать конец файла
    Регулярное выражение . мета-символ должен соответствовать только любому символу, кроме <CR> или <LF>. Существует ошибка, которая позволяет ему соответствовать концу файла, если последняя строка в файл не завершается <CR> или <LF>. Однако . не будет соответствовать пустой файл.

    например, файл с именем "test.txt", содержащий одну строку x, без расторжения <CR> или <LF>, будет соответствовать следующее:

    findstr /r x......... test.txt
    

    эта ошибка была подтверждена на XP и Win7.

    то же самое, кажется, верно для отрицательных наборов символов. Что-то вроде [^abc] будет соответствовать концу файла. Положительные наборы символов, такие как [abc] кажется, работает нормально. Я тестировал это только на Win7.


    findstr иногда неожиданно зависает при поиске больших файлов.

    я не подтвердил точные условия, размеры и границы. Я подозреваю, что любой файл размером больше 2GB может быть под угрозой.

    у меня есть опыт с этим, так что это больше, чем просто размер файла. Это похоже на то, что это может быть вариация на FINDSTR зависает на XP и Windows 7, Если перенаправленный ввод не заканчивается LF, но, как показано, эта конкретная проблема проявляется при вводе не перенаправлены.

    следующий сеанс командной строки (Windows 7) демонстрирует, как findstr может зависать при поиске файла 3GB.

    C:\Data\Temp14-04>echo 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890> T100B.txt
    
    C:\Data\Temp14-04>for /L %i in (1,1,10) do @type T100B.txt >> T1KB.txt
    
    C:\Data\Temp14-04>for /L %i in (1,1,1000) do @type T1KB.txt >> T1MB.txt
    
    C:\Data\Temp14-04>for /L %i in (1,1,1000) do @type T1MB.txt >> T1GB.txt
    
    C:\Data\Temp14-04>echo find this line>> T1GB.txt
    
    C:\Data\Temp14-04>copy T1GB.txt + T1GB.txt + T1GB.txt T3GB.txt
    T1GB.txt
    T1GB.txt
    T1GB.txt
            1 file(s) copied.
    
    C:\Data\Temp14-04>dir
     Volume in drive C has no label.
     Volume Serial Number is D2B2-FFDF
    
     Directory of C:\Data\Temp14-04
    
    2014/04/08  04:28 PM    <DIR>          .
    2014/04/08  04:28 PM    <DIR>          ..
    2014/04/08  04:22 PM               102 T100B.txt
    2014/04/08  04:28 PM     1 020 000 016 T1GB.txt
    2014/04/08  04:23 PM             1 020 T1KB.txt
    2014/04/08  04:23 PM         1 020 000 T1MB.txt
    2014/04/08  04:29 PM     3 060 000 049 T3GB.txt
                   5 File(s)  4 081 021 187 bytes
                   2 Dir(s)  51 881 050 112 bytes free
    C:\Data\Temp14-04>rem Findstr on the 1GB file does not hang
    
    C:\Data\Temp14-04>findstr "this" T1GB.txt
    find this line
    
    C:\Data\Temp14-04>rem On the 3GB file, findstr hangs and must be aborted... even though it clearly reaches end of file
    
    C:\Data\Temp14-04>findstr "this" T3GB.txt
    find this line
    find this line
    find this line
    ^C
    C:\Data\Temp14-04>
    

    примечание, Я проверил в шестнадцатеричном редакторе, что все строки заканчиваются на CRLF. Единственный аномалия заключается в том, что файл заканчивается 0x1A из-за путь copy работает. Обратите внимание, однако, что эта аномалия не вызывает проблем на "small" файлы.

    с дополнительным тестированием я подтвердил следующее:

    • используя copy С /b опция для двоичных файлов предотвращает добавление 0x1A персонаж, и findstr не зависает в файле 3GB.
    • завершение файла 3GB с другим символом также вызывает findstr вешать.
    • на 0x1A символ не вызывает никаких проблем в "маленьком" файле. (Аналогично для других символами.)
    • добавлять CRLF после 0x1A решает проблему. (LF само по себе было бы достаточно.)
    • используя type для передачи файла в findstr работает, не висит. (Это может быть связано с побочным эффектом либо type или | это вставляет дополнительный конец строки.)
    • использовать перенаправление ввода < вызывает findstr вешать. но это ожидается; как объясняется в dbenham по пост: "перенаправленный ввод должен заканчиваться на LF".

    когда несколько команд заключены в круглые скобки и перенаправлены файлы на весь блок:

    < input.txt (
       command1
       command2
       . . .
    ) > output.txt
    

    ... затем файлы остаются открытыми до тех пор, пока команды в блоке активны, поэтому команды могут перемещать указатель файла перенаправленных файлов. И больше, и команды FIND перемещают указатель Stdin-файла в начало файла перед его обработкой, поэтому один и тот же файл может обрабатываться несколько раз внутри блока. Например, это код:

    more < input.txt >  output.txt
    more < input.txt >> output.txt
    

    ... получите тот же результат, что и этот:

    < input.txt (
       more
       more
    ) > output.txt
    

    этот код:

    find    "search string" < input.txt > matchedLines.txt
    find /V "search string" < input.txt > unmatchedLines.txt
    

    ... получите тот же результат, что и этот:

    < input.txt (
       find    "search string" > matchedLines.txt
       find /V "search string" > unmatchedLines.txt
    )
    

    FINDSTR отличается; это делает не переместите указатель файла Stdin из текущего положения. Например, этот код вставляет новую строку после строки поиска:

    call :ProcessFile < input.txt
    goto :EOF
    
    :ProcessFile
       rem Read the next line from Stdin and copy it
       set /P line=
       echo %line%
       rem Test if it is the search line
       if "%line%" neq "search line" goto ProcessFile
    rem Insert the new line at this point
    echo New line
    rem And copy the rest of lines
    findstr "^"
    exit /B
    

    мы можем хорошо использовать эту функцию с помощью вспомогательной программы, которая позволяет нам переместите указатель файла перенаправленного файла, как показано в .

    об этом поведении впервые сообщили джеб at этот пост.


    редактировать 2018-08-18: новая ошибка FINDSTR сообщается

    команда FINDSTR имеет странную ошибку, которая происходит, когда эта команда используется для отображения символов в цвете, и вывод такой команды перенаправляется на устройство CON. Подробнее о как использовать команду FINDSTR для отображения текста в цвете, см. этой теме.

    когда вывод этой формы команды FINDSTR перенаправляется на CON, что-то странное происходит после вывода текста в желаемом цвете: весь текст после его вывода Как "невидимые" символы, хотя более точное описание заключается в том, что текст выводится как черный текст на черном фоне. Исходный текст появится, если вы используете команду COLOR для сброса переднего плана и фона цвета всего экрана. Однако, когда текст "невидим", мы можем выполнить команду SET /P, поэтому все введенные символы не будут отображаться на экране. Это поведение может использоваться для ввода паролей.

    @echo off
    setlocal
    
    set /P "=_" < NUL > "Enter password"
    findstr /A:1E /V "^$" "Enter password" NUL > CON
    del "Enter password"
    set /P "password="
    cls
    color 07
    echo The password read is: "%password%"
    

    Я хотел бы сообщить об ошибке относительно раздела источник данных для поиска в первом ответе при использовании тире (–) или em dash (-) в имени файла.

    более конкретно, если вы собираетесь использовать первый вариант - имена файлов, указанные в качестве аргументов, то файл не будет найден. Как только вы используете любой вариант 2 -stdin через перенаправление или 3 поток данных из трубы, Она будет найти файл.

    например, этот простой пакетный скрипт:

    echo off
    chcp 1250 > nul
    set INTEXTFILE1=filename with – dash.txt
    set INTEXTFILE2=filename with — dash.txt
    
    rem 3 way of findstr use with en dashed filename
    echo.
    echo Filename with en dash:
    echo.
    echo 1. As argument
    findstr . "%INTEXTFILE1%"
    echo.
    echo 2. As stdin via redirection
    findstr . < "%INTEXTFILE1%"
    echo.
    echo 3. As datastream from a pipe
    type "%INTEXTFILE1%" | findstr .
    echo.
    echo.
    rem The same set of operations with em dashed filename
    echo Filename with em dash:
    echo.
    echo 1. As argument
    findstr . "%INTEXTFILE2%"
    echo.
    echo 2. As stdin via redirection
    findstr . < "%INTEXTFILE2%"
    echo.
    echo 3. As datastream from a pipe
    type "%INTEXTFILE2%" | findstr .
    echo.
    
    pause
    

    выведет:

    имя файла с En dash:

    1. в качестве аргумента
      FINDSTR: не удается открыть имя файла с помощью-dash.txt

    2. как stdin через перенаправление
      Я файл с тире.

    3. как поток данных из трубы
      Я файл с en тире.

    имя файла с EM dash:

    1. в качестве аргумента
      FINDSTR: не удается открыть имя файла с помощью-dash.txt

    2. как stdin через перенаправление
      Я файл с тире.

    3. как поток данных из трубы
      Я файл с тире.

    надеюсь, что это помогает.

    М.


    /D совет для нескольких каталогов: поместите список каталогов перед строкой поиска. Все это работает:

    findstr /D:dir1;dir2 "searchString" *.*
    findstr /D:"dir1;dir2" "searchString" *.*
    findstr /D:"\path\dir1\;\path\dir2\" "searchString" *.*
    

    как и ожидалось, путь относительно местоположения, если вы не начнете каталоги с \. Окружая тропу с " является необязательным, если нет пробелов в именах каталогов. Конец \ является необязательным. Выход location будет включать в себя любой путь, который вы ему даете. Он будет работать с или без окружения списка каталогов с ".