Які недокументовані функції та обмеження команди Windows FINDSTR?


188

Команда Windows FINDSTR жахливо задокументована. Є дуже елементарна довідка з командного рядка, доступна через FINDSTR /?, або HELP FINDSTR, але вона надзвичайно неадекватна. На сайті https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/findstr є додаткова документація в Інтернеті .

Існує багато функцій та обмежень FINDSTR, про які навіть не натякано в документації. Також їх не можна було передбачити без попередніх знань та / або ретельного експерименту.

Отже, питання полягає в тому, що таке недокументовані функції та обмеження FINDSTR?

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

A) Розробники можуть повністю скористатися функціями, які є там.

Б) Розробники не витрачають час на запитання, чому щось не працює, коли здається, що має бути.

Будь ласка, переконайтеся, що ви знаєте наявну документацію, перш ніж відповідати. Якщо інформація охоплюється HELP, то вона тут не належить.

Також це не місце для показу цікавих застосувань FINDSTR. Якщо логічна особа могла б передбачити поведінку певного використання FINDSTR на основі документації, вона не належить тут.

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


15
Або, як альтернативи, ви можете угробити лайно нелегальні утиліти MS взагалі і установку / використання grepяких є дуже добре зрозуміло і документований :-) Див stackoverflow.com/questions/2635740 / ... , наприклад.
paxdiablo

17
У будь-якому випадку, якщо ви можете використовувати щось інше, ніж FINDSTR, то це вкрай не радимо. Але деякі люди знаходяться в середовищах, коли сторонні комунальні послуги заборонені.
dbenham

4
Не вчинено правопорушень. Я серйозно подумав про те, щоб укласти свою власну відмову від FINDSTR, яка була схожа на ваш коментар! :)
dbenham

41
Я шокований і розчарований, хтось знайде це питання "Неконструктивним" і проголосує за закриття. Багато питань замислювалося над питанням, щоб уникнути "думки, дебатів, аргументів, опитування чи розширеної дискусії". Запитання було розміщено протягом 3,5 місяців, і жодного з цитованих негативів не було. Парна відповідь наповнена фактами і вимагає багато годин ретельного дослідження та експериментів.
dbenham

6
Деяких читачів може зацікавити історичний контекст команди findstr: blogs.msdn.com/b/oldnewthing/archive/2012/11/28/10372436.aspx
Гаррі Джонстон

Відповіді:


279

Передмова
Багато інформації в цій відповіді зібрано на основі експериментів, проведених на машині Vista. Якщо прямо не вказано інше, я не підтвердив, чи стосується ця інформація до інших версій Windows.

Вихід FINDSTR
Документація ніколи не намагається пояснювати вихід FINDSTR. Це натякає на те, що друкуються відповідні рядки, але нічого більше.

Формат виведення рядка відповідності такий:

ім'я файлу: рядокNumber: lineOffset: текст

де

fileName: = Ім'я файлу, що містить рядок відповідності. Ім'я файлу не друкується, якщо запит був явним чином для одного файлу, або при пошуку вхідного каналу або перенаправленого вводу. При надрукуванні ім'я файлу завжди буде містити будь-яку інформацію про шлях. Додаткова інформація про шлях буде додана, якщо використовується/Sпараметр. Друкований шлях завжди є відносно наданого шляху або відносно поточного каталогу, якщо його немає.

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

lineNumber: = Номер рядка відповідного рядка, представлений у вигляді десяткового значення з 1, що представляє 1-й рядок вводу. Друкується лише якщо/Nвказана опція.

lineOffset: = Десяткове байтове зміщення початку відповідного рядка, причому 0 представляє 1-й символ першого рядка. Друкується лише якщо/Oвказана опція. Це не зміщення матчу в рядку. Це кількість байтів від початку файлу до початку рядка.

text = Двійкове представлення відповідного рядка, включаючи будь-який <CR> та / або <LF>. Від бінарного виводу нічого не залишається, так що цей приклад, який відповідає всім рядкам, створить точну бінарну копію вихідного файлу.

FINDSTR "^" FILE >FILE_COPY

Параметр / A встановлює колір файлуName :, lineNumber :, and lineOffset: only output. Текст відповідного рядка завжди виводиться з поточним кольором консолі. Параметр / A діє лише тоді, коли вихід відображається безпосередньо на консолі. Параметр / A не має ефекту, якщо вихідний файл буде переспрямований у файл або на трубопроводі. Дивіться редакцію 2018-08-18 у відповіді Aacini для опису поведінки баггі, коли вихід перенаправляється на CON.

Більшість керуючих символів та багато розширених символів ASCII відображаються у вигляді крапок на XP
FINDSTR на XP, на екрані відображається більшість недрукованих контрольних символів із відповідних ліній у вигляді крапок (періодів). Наступні контрольні символи - винятки; вони відображаються як самі: вкладка 0x09, 0x0A LineFeed, вертикальна вкладка 0x0B, подача форми 0x0C, повернення перевезення 0x0D.

XP FINDSTR також перетворює ряд розширених символів ASCII в крапки. Розширені символи ASCII, які відображаються у вигляді точок у XP, такі ж, як і ті, що трансформуються, коли вони надходять у командному рядку. Дивіться розділ "Обмеження символів для параметрів командного рядка - Розширене перетворення ASCII" , пізніше в цій публікації

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

Vista та Windows 7 завжди відображають усі символи як себе, ніколи не крапки.

Коди повернення (ERRORLEVEL)

  • 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)
Параметри /G:fileта /C:stringпараметри можуть поєднуватися. /C:stringМожна вказати кілька варіантів. Якщо /G:fileвказано кілька варіантів, використовується лише останній. Якщо використовується /G:fileабо /C:stringвикористовується, всі аргументи, що не є опціями, вважаються файлами для пошуку. Якщо ні, /G:fileні/C:string не використовується, то перший аргумент, що не є варіантом, трактується як список пошукових термінів, обмежений пробілом.

Імена файлів не повинні цитуватися у файлі під час використання /F:FILEпараметра.
Імена файлів можуть містити пробіли та інші спеціальні символи. Більшість команд вимагають, щоб такі імена файлів були цитовані. Але параметр FINDSTR /F:files.txtвимагає, щоб назви файлів у файлах.txt НЕ котирувались. Файл не буде знайдено, якщо ім'я буде вказано.

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

b1.txt
b.txt2
c.txt

Наступна команда успішно знайде всі 3 файли:

findstr /m "^" *.txt

b.txt2відповідає тому, що відповідна коротка назва B9F64~1.TXTвідповідає. Це відповідає поведінці всіх інших команд Windows.

Але помилка з параметрами /Dта /Sпараметрами змушує знаходити лише наступні командиb1.txt

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

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

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

Команди працюють без помилок, якщо однакові імена файлів створюються на машині, де вимкнено генерацію імен NTFS 8.3. Звичайно b.txt2, не знайдеться, але c.txtбуло б знайдено належним чином.

Не всі короткі імена викликають помилку. Усі випадки помилок, які я бачив, містять розширення, яке перевищує 3 символи, з коротким ім'ям 8.3, яке починається так само, як і звичайне ім'я, яке не вимагає 8.3 імені.

Помилка підтверджена в XP, Vista та Windows 7.

Недруковані символи та /Pопція
Ця /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можливість пропустити файл.

Трубопровідний та перенаправлений вхід, можливо, <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 буде зависати нескінченно раз на ньому доходить до кінця переспрямованого файлу.

Останній рядок даних Piped може бути проігнорований, якщо він складається з одного символу
Якщо вхід введено в дію і останній рядок складається з одного символу, за яким не слідує <LF>, то FINDSTR повністю ігнорує останній рядок.

Приклад - перша команда з одним символом і не <LF>дає збіги, але друга команда з двома символами працює добре, як і третя команда, що має один символ із закінченням нового рядка.

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

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

> echo x| findstr "^"
x

Повідомляє користувач DosTips Sponge Belly при новому помилку findstr . Підтверджено на XP, Windows 7 та Windows 8. Ще не чув про Vista. (У мене більше немає Vista для тестування).

Синтаксис
опцій Опції можуть бути префіксальні або з, /або - Опції можуть бути об'єднані після одиничного /або -. Однак список об'єднаних опцій може містити щонайменше один варіант багатохарактерних функцій, такий як OFF або F :, а опція з декількома символами повинна бути останньою опцією у списку.

Нижче наведені всі еквівалентні способи вираження регрес-пошуку, нечутливого до регістру, для будь-якого рядка, що містить і "привіт", і "до побачення" в будь-якому порядку

  • /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. Помилка призводить до правильної довжини виразу> 511 FINDSTR: Search string too long..

У Windows XP довжина пошукового рядка, мабуть, коротша. Помилка Findstr: "Пошуковий рядок занадто довгий": Як витягнути і підрівняти підрядку в циклі "for"? Ліміт XP становить 127 байт як для прямого пошуку, так і для регулярного вибору.

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

Трубопровідні дані та перенаправлений вхід обмежені 8191 байтом на рядок. Цей ліміт є "особливістю" FINDSTR. Це не властиво трубам або перенаправленню. FINDSTR, використовуючи переспрямований stdin або трубопровідний вхід, ніколи не буде відповідати жодному рядку, що становить> = 8k байтів. Рядки> = 8k генерують повідомлення про помилку в stderr, але ERRORLEVEL все ще дорівнює 0, якщо рядок пошуку знайдено принаймні в одному рядку щонайменше в одному файлі.

Тип пошуку за замовчуванням: Literal vs Regular Expression
/C:"string" - Типовим є / L literal. Явне поєднання параметра / L з / C: "рядок", безумовно, працює, але є зайвим.

"string argument"- За замовчуванням залежить зміст самого першого рядка пошуку. (Пам’ятайте, що <space> використовується для розмежування рядків пошуку.) Якщо перший рядок пошуку є дійсним регулярним виразом, що містить принаймні один невідбутий мета-символ, то всі рядки пошуку розглядаються як регулярні вирази. В іншому випадку всі рядки пошуку трактуються як буквальні. Наприклад, "51.4 200"трактуватимуться як два регулярних вирази, тому що перший рядок містить непотрібну крапку, тоді як "200 51.4"буде розглянуто як два літерали, оскільки перший рядок не містить мета-символів.

/G:file- За замовчуванням залежить вміст першого не порожнього рядка у файлі. Якщо перший рядок пошуку є дійсним регулярним виразом, який містить щонайменше один невідбутий мета-символ, то всі рядки пошуку розглядаються як регулярні вирази. В іншому випадку всі рядки пошуку трактуються як буквальні.

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

BUG - Вказівка ​​декількох буквальних рядків пошуку може дати ненадійні результати

Наведений нижче простий приклад FINDSTR не в змозі знайти відповідність, хоч і повинен.

echo ffffaaa|findstr /l "ffffaaa faffaffddd"

Ця помилка була підтверджена в Windows Server 2003, Windows XP, Vista та Windows 7.

На основі експериментів, FINDSTR може не вдатися, якщо будуть виконані всі наступні умови:

  • Для пошуку використовується декілька буквальних рядків пошуку
  • Рядки пошуку мають різну довжину
  • Короткий рядок пошуку має деяку кількість перекриття з довшою пошуковою рядком
  • Пошук відрізняється від регістру (немає /Iваріантів)

У кожному невдачі, який я бачив, це завжди одна з коротших рядків пошуку, яка не працює.

Для отримання додаткової інформації див. Чому цей приклад FINDSTR з кількома буквальними рядками пошуку не відповідає?

Котирування та зворотні коси в аргументах командного рядка
Примітка - коментарі користувача MC ND відображають фактично жахливо складні правила для цього розділу. Задіяні 3 окремі фази розбору:

  • Перший cmd.exe може вимагати, щоб деякі цитати не були використані як ^ "(насправді нічого не стосується FINDSTR)
  • Далі FINDSTR використовує аналізатор аргументів MS C / C ++ до 2008 року , який має спеціальні правила для "та \
  • Після завершення аналізатора аргументів, FINDSTR додатково розглядає \, а потім буквено-цифровий символ як буквальний, але \ з наступним не-альфа-числовим символом як символ втечі

Решта цього виділеного розділу не на 100% вірна. Він може слугувати посібником для багатьох ситуацій, але вищезазначені правила потрібні для повного розуміння.

Уникнення
цитати в рядках пошуку в командному рядку Цитати в рядках пошуку в командному рядку повинні бути усунені з подібною косою рисою \". Це справедливо як для буквальних, так і для регулярних виразів пошуку. Цю інформацію було підтверджено в XP, Vista та Windows 7.

Примітка. Цитата також може знадобитися уникати для аналізатора CMD.EXE, але це не має нічого спільного з FINDSTR. Наприклад, для пошуку однієї цитати ви можете використовувати:

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

Уникнення зворотного косого ряду в рядках пошуку
в прямому рядку командного рядка Зворотний проріз у рядку пошуку буквально може бути представлений як \або як \\. Вони, як правило, рівнозначні. (Можливо, у Vista є випадкові випадки, коли зворотну косу рису потрібно завжди уникати, але у мене більше немає машини для перевірки) .

Але є деякі особливі випадки:

При пошуку послідовних зворотних косих рис, все , крім останнього необхідно екранувати. Останній зворотний нахил може необов'язково уникнути.

  • \\можна кодувати як \\\або\\\\
  • \\\можна кодувати як \\\\\або\\\\\\

Пошук одного або декількох косих рисок перед цитатою химерний. Логіка підказує, що цитата повинна бути відхилена, і кожен з провідних зворотних косої риски повинен бути уникнути, але це не працює! Натомість, кожен з провідних косих косих ринків повинен бути подвійним, а цитата - нормальною:

  • \" повинні бути кодовані як \\\\\"
  • \\" повинні бути кодовані як \\\\\\\\\"

Як було зазначено раніше, одна або кілька котирувань, що увійшли, можуть також вимагати переходу ^для аналізатора CMD

Інформація в цьому розділі підтверджена в XP та Windows 7.

Уникнення зворотного косого ряду в рядках пошуку регулярного вираження командного рядка

  • Тільки Vista: зворотна коса в регулярному виразі повинна бути або подвійною \\\\, а або одинаковою втечею в наборі класів символів, як [\\]

  • XP та Windows 7: Зворотна косою рисою завжди може бути представлена ​​як [\\]. Зазвичай це може бути представлено як \\. Але це ніколи не спрацьовує, якщо зворотний косий передує уникненій цитаті.

    Один або декілька косих косих рядків, що вийшли вперед, або повинні бути подвійними, або ж закодованими як [\\]

    • \"може кодуватися як \\\\\"або[\\]\"
    • \\"можуть бути кодовані як \\\\\\\\\"або [\\][\\]\"або\\[\\]\"

Уникнення
котирування та зворотного косу в межах / G: ФАЙЛ буквальних рядків пошуку. Автономні лапки та зворотні косої риски в прямому рядку пошуку, вказаному в / G: файл не потрібно уникати, але вони можуть бути.

"і \"є рівнозначними.

\і \\є рівнозначними.

Якщо наміром знайти \\, потрібно хоча б уникнути провідного косого кута. І те, \\\і \\\\робота.

Якщо наміром знайти \ ", то потрібно принаймні ухилити провідну косу рису \\" і \\\"працювати.

Уникнення котирування і зворотного косу в межах / G: ФАЙЛ пошуку рядків пошуку регулярного виразів
Це єдиний випадок, коли послідовності втечі працюють відповідно до документації, як очікувалося. Цитата не є метасимволом регулярних виразів, тому її не потрібно уникати (але може бути). Зворотна коса - це метасимвол регулярних виразів, тому його потрібно уникати.

Обмеження символів для параметрів командного рядка - Розширене перетворення ASCII
Нульовий символ (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>. Найпростіший спосіб включити непарні символи, як <CR>і, <LF>це ввести їх у змінну середовища та використовувати затримку розширення в аргументі командного рядка.

Обмеження символів для рядків, знайдених у файлах, визначених параметрами / G: FILE та / F: FILE Параметр
nul (0x00) може відображатися у файлі, але він функціонує як термінатор рядка C. Будь-які символи після нульового символу трактуються як інший рядок, як ніби вони знаходяться в іншому рядку.

<CR>І <LF>символи розглядаються як лінійні термінатори , які завершуються рядки, і не включаються до рядка.

Всі інші однобайтові символи ідеально включаються в рядок.

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

Однак команда TYPE перетворює UTF-16LE з BOM в однобайтовий набір символів, тому така команда, як нижче, буде працювати з UTF-16LE з BOM.

type unicode.txt|findstr "search"

Зауважте, що точки коду Unicode, які не підтримуються вашою активною кодовою сторінкою, будуть перетворені в ?символи.

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

Можна шукати багатобайтові символи UTF-8, якщо ви введете пошукову рядок у закодований файл UTF-8 (без BOM) та скористаєтесь опцією / G.

Кінець рядка
FINDSTR розбиває рядки відразу після кожного <LF>. Наявність або відсутність <CR> не впливає на розриви рядків.

Пошук по розривах рядків
Як і очікувалося, .метахарактер регулярних вирівнювань не буде відповідати <CR> або <LF>. Але можна шукати перерву рядка за допомогою рядка пошуку командного рядка. І символи <CR>, і <LF> повинні бути чітко узгоджені. Якщо знайдено багаторядковий збіг, друкується лише 1-й рядок відповідності. Потім FINDSTR подвоюється назад до другого рядка в джерелі і починає пошук знову заново - на зразок функції типу "погляд вперед".

Припустимо, у TEXT.TXT є цей вміст (це може бути стиль Unix або Windows)

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 є неточним, оскільки єдиний спосіб зіставити <CR> або <LF> - це вираз діапазону символів класу регулярних виразів, який затискає символи EOL.

  • [<TAB>-<0x0B>] відповідає <LF>, але він також відповідає <TAB> і <0x0B>

  • [<0x0C>-!] відповідає <CR>, але він також відповідає <0x0C> і!

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

Відповідь продовжено в частині 2 нижче ...


46
Видатна повнота. Якби всі відповіді в Інтернеті були такими.
Майк Віенс

1
ми зіткнулися з проблемою з addpath.batвід Q141344 і Findstr, які можуть бути пов'язані з проблемою висить Win7 згадувалося вище. Я створив кімнату чату, щоб спробувати відстежити це для всіх, хто цікавиться: chat.stackoverflow.com/rooms/13177/…
matt wilkie

2
EDIT - Описане відображення контрольних символів як крапок на XP. Також задокументовано помилки /Sта /Dпараметри, що випливають із коротких імен файлів 8,3.
dbenham

1
EDIT - 1) Імена файлів у файлі, визначеному / F: FILE не повинні цитуватися. 2) Трансформація розширених символів ASCII впливає як на рядки пошуку, так і на імена файлів, коли вони надаються в командному рядку.
dbenham

1
EDIT - Додано помилку, коли останній рядок вводу даних ігнорується, якщо він складається з одного символу без<LF>
dbenham

64

Відповідь продовжено з частини 1 вище - я зіткнувся з межею відповіді 30 000 символів :-(

Обмежені регулярні вирази (регулярні вирази) Підтримка
FINDSTR для регулярних виразів вкрай обмежена. Якщо його немає в документації HELP, воно не підтримується.

Крім того, виражені регулярні вирази, що підтримуються, реалізуються абсолютно нестандартним чином, таким чином, що результати можуть бути різними, тоді, як очікується, виходять із чогось, наприклад, grep або perl.

Положення Regex Line анкерів ^ і $
^ збігаються з початком вхідного потоку, а також з будь-якою позицією відразу після <LF>. Оскільки FINDSTR також розбиває рядки після <LF>, простий регулярний вираз "^" завжди відповідатиме всім рядкам у файлу, навіть двійковим файлом.

$відповідає будь-якій позиції, що передує <CR>. Це означає, що рядок пошуку регулярного виразу, що містить $, ніколи не буде відповідати жодним рядкам у текстовому файлі стилю Unix, а також не буде відповідати останньому рядку текстового файлу Windows, якщо в ньому відсутній маркер EOL <CR> <LF>.

Примітка. Як було обговорено раніше, вкладений та перенаправлений вхід до FINDSTR може бути <CR><LF>доданий, що не є у вихідному коді. Очевидно, це може вплинути на пошук регулярного виразу$ .

Будь-який рядок пошуку з символами до ^або після $цього завжди не знайде відповідності.

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

/ B функціонує так само, як ^ на початку рядка пошуку регулярних виразів.

/ E функціонує так само, як $ в кінці рядка пошуку регулярних виразів.

/ X функціонує так само, як і ^на початку, і $в кінці рядка пошуку регулярних виразів.

Межа слів Regex
\< повинна бути найпершим терміном у регулярному вираженні. Регекс не відповідатиме нічого, якщо перед ним передують будь-які інші символи.\<відповідає або самому початку введення, початку рядка (позиція негайно після <LF>), або позиції, що безпосередньо слідує за будь-яким символом "не слово". Наступним символом не повинно бути символу "слова".

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

Ось повний перелік символів, що не мають слова, представлені у вигляді десяткового байтового коду. Примітка - цей список був складений на машині США. Я не знаю, який вплив можуть мати інші мови на цей список.

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

Діапазони класів символів Regex [xy]
Діапазони класів символів не працюють, як очікувалося. Дивіться це запитання: Чому findstr не справляється із справою належним чином (за деяких обставин)? разом із цією відповіддю: https://stackoverflow.com/a/8767815/1012053 .

Проблема полягає в тому, що FINDSTR не позначає символів за значенням їх байтового коду (зазвичай його називають кодом ASCII, але ASCII визначається лише від 0x00 - 0x7F). Більшість застосувань регулярного вираження розглядають [AZ] як усі великі великі літери англійською мовою. Але FINDSTR використовує послідовність зіставлення, яка приблизно відповідає тому, як працює SORT. Так [AZ] включає повний англійський алфавіт, як верхній, так і нижній регістри (крім «а»), а також неанглійські букви з діакритикою.

Нижче наводиться повний перелік усіх символів, підтримуваних 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 та BUG
Не тільки FINDSTR обмежений максимальним рівнем 15 класів символів у межах регулярного вираження, він не вдається належним чином обробити спробу перевищення ліміту. Використання 16 або більше термінів класу символів призводить до того, що інтерактивне спливаюче вікно Windows із зазначенням "Утиліта Find String (QGREP) зіткнулася з проблемою і її потрібно закрити. Просимо вибачення за незручності". Текст повідомлення дещо відрізняється залежно від версії Windows. Ось один приклад FINDSTR, який не вдасться:

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.

Не вдалося здійснити пошук Regex (і може зависати нескінченно), якщо вони включають код байту 0xFF (десяткова 255)
Будь-який пошук регулярного вибору, що включає код байту 0xFF (десятковий 255), не вдасться. Він не вдається, якщо байт-код 0xFF включений безпосередньо, або якщо він неявно включений в діапазон класів символів. Пам’ятайте, що діапазони класів символів FINDSTR не порівнюють символів на основі значення байтового коду. Символ <0xFF>з'являється відносно рано в послідовності зіставлення між символами <space>та <tab>. Тож будь-який діапазон класів символів, що включає в себе і те, <space>і інше, <tab>буде невдалим.

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

У мене більше немає доступу до машини Vista, тому мені не вдалося протестувати на Vista.

Помилка Regex: .і [^anySet]може відповідати End-Of-File
. .Мета-символ regex повинен відповідати лише будь-якому символу, крім <CR>або <LF>. Існує помилка, яка дозволяє йому відповідати файлу End-Of-File, якщо останній рядок у файлі не закінчується <CR>або <LF>. Однак .порожній файл не збігатиметься.

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

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

Ця помилка була підтверджена на XP та Win7.

Це ж, здається, справедливо і для наборів негативних символів. Щось подібне [^abc]відповідатиме End-Of-File. Наче позитивні набори символів, [abc]здається, працюють добре. Я протестував це лише на Win7.


1
findstr також баггі, що займається великими файлами. Файли> 2 Гб можуть спричинити зависання Findstr. Це не завжди буває. Підтверджуючи помилку, я шукав файл розміром 2,3 Гб, який не висів. Він висить, навіть якщо шукати лише один файл. Вирішення проблеми полягає в проходженні виходу typeв findstr.
Розчарований

Це, мабуть, також варто чітко згадати, що findstrпідтримує кілька /c:рядків пошуку. Я знаю, що ваші відповіді це демонструють. Але це щось не документально підтверджене; і я був дуже здивований, дізнавшись про цю функцію, використовуючи findstrбез неї кілька років.
Розчарувались

@CraigYoung - Ви маєте рацію щодо джерел пошукових рядків. Я відредагував свою відповідь, дякую.
dbenham

1
При подальшому розслідуванні це виглядає як варіація щодо LFдокумента, який ви задокументували. Я зрозумів, що мій тестовий файл не закінчився, LFоскільки copyдля його створення використовував його в режимі додавання. Я поставив сеанс командного рядка, щоб продемонструвати проблему у відповідь ( stackoverflow.com/a/22943056/224704 ). Зауважте, що введення не переспрямоване, і все ж пошук зависає. Точно така ж команда пошуку не зависає з меншими файлами, які аналогічно не закінчуються LF.
Розчарований

1
Нова знахідка (Win7): findstr /R /C:"^[0-9][0-9]* [0-3][0-9][0-9]-[0-9][0-9]:[0-5][0-9]:[0-5][0-9]\.[0-9][0-9]* [0-9]*\.[0-9]*"(15 класів символів) - ErrorLevel = -1073740791 (0xC0000409), діалогове вікно помилки : Find String (QGREP) Utility has stopped working; після видалення одного класу або двох мета-символів ( *\.) він працює ...
aschipfl

7

findstr іноді зависає несподівано під час пошуку великих файлів.

Я не підтвердив точні умови чи розміри меж. Я підозрюю, що будь-який файл розміром 2 ГБ може загрожувати.

Я мав неоднозначний досвід з цим, тому це більше, ніж просто розмір файлу. Схоже, це може бути зміна на вивісі FINDSTR на XP та Windows 7, якщо перенаправлений вхід не закінчується на LF , але, як показано, ця конкретна проблема виявляється, коли вхід не перенаправлений.

Наступний сеанс командного рядка (Windows 7) демонструє, як findstrможна зависати при пошуку файлу 3 Гб.

C:\Data\Temp\2014-04>echo 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890> T100B.txt

C:\Data\Temp\2014-04>for /L %i in (1,1,10) do @type T100B.txt >> T1KB.txt

C:\Data\Temp\2014-04>for /L %i in (1,1,1000) do @type T1KB.txt >> T1MB.txt

C:\Data\Temp\2014-04>for /L %i in (1,1,1000) do @type T1MB.txt >> T1GB.txt

C:\Data\Temp\2014-04>echo find this line>> T1GB.txt

C:\Data\Temp\2014-04>copy T1GB.txt + T1GB.txt + T1GB.txt T3GB.txt
T1GB.txt
T1GB.txt
T1GB.txt
        1 file(s) copied.

C:\Data\Temp\2014-04>dir
 Volume in drive C has no label.
 Volume Serial Number is D2B2-FFDF

 Directory of C:\Data\Temp\2014-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\Temp\2014-04>rem Findstr on the 1GB file does not hang

C:\Data\Temp\2014-04>findstr "this" T1GB.txt
find this line

C:\Data\Temp\2014-04>rem On the 3GB file, findstr hangs and must be aborted... even though it clearly reaches end of file

C:\Data\Temp\2014-04>findstr "this" T3GB.txt
find this line
find this line
find this line
^C
C:\Data\Temp\2014-04>

Зауважте, я перевірив у шестигранному редакторі, що всі рядки закінчуються CRLF. Єдина аномалія - ​​це те, що файл припиняється 0x1Aзавдяки способу copyроботи . Зауважте, що ця аномалія не спричиняє проблем із "малими" файлами .

Додатковим тестуванням я підтвердив наступне:

  • Використання copyз /bопцією для бінарних файлів запобігає доданню 0x1Aсимволу і findstrне зависає на 3 Гб.
  • Закінчення файлу об'ємом 3 ГБ з іншим символом також призводить findstrдо зависання.
  • 0x1AХарактер не викликає жодних - яких проблем на «невеликий» файл. (Аналогічно для інших символів, що закінчуються.)
  • Додавання CRLFпісля 0x1Aвирішує проблему. ( LFсаме по собі, мабуть, вистачить.)
  • Використовується typeдля передачі файлу у findstrтвори без підвішування. (Це може бути пов’язано з побічним ефектом того typeчи іншого, |який вставляє додатковий кінець рядка.)
  • Використання перенаправленого вводу <також призводить findstrдо зависання. Але цього очікується; як пояснено в дописі dbenham : "переспрямований вхід повинен закінчуватися LF" .

1
+1, я можу підтвердити проблему на своїй машині Win7. Файл розміром 2 Гбіт висів, коли останнього символу не було <LF>. Файл на два байти менше не висів. Дуже противно!
dbenham

6

Коли кілька команд укладені в круглі дужки, і до них перенаправлені файли до всього блоку:

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

... тоді файли залишаються відкритими до тих пір, поки команди в блоці будуть активними, тому команди можуть переміщувати покажчик файлів на перенаправлені файли. І команди БІЛЬШЕ, і ЗНАЙТЕ переміщення вказівника на файл 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

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

Про цю поведінку вперше повідомив jeb на цій посаді .


EDIT 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%"

2

Я хотів би повідомити про помилку щодо розділу " Джерело даних" для пошуку у першій відповіді під час використання en dash (-) або em dash (-) у назві файлу.

Більш конкретно, якщо ви збираєтеся використовувати перший варіант - назви файлів, вказані як аргументи , файл не буде знайдений. Як тільки ви скористаєтеся або варіантом 2 - stdin через перенаправлення, або 3 - потоком даних з труби , findstr знайде файл.

Наприклад, цей простий пакетний сценарій:

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

надрукує:

Ім'я файлу з тире:

  1. Як аргумент
    FINDSTR: Неможливо відкрити ім'я файлу за допомогою - dash.txt

  2. Як stdin через переадресацію,
    я файл із тире.

  3. Як потік даних з труби,
    я являю собою файл із тире.

Ім'я файлу з em dash:

  1. Як аргумент
    FINDSTR: Неможливо відкрити ім'я файлу за допомогою - dash.txt

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

  3. Як потік даних з труби,
    я - файл із тире.

Сподіваюся, це допомагає.

М.


1
Привіт матро, хоча ваші коментарі можуть бути правильними, я не впевнений, що вони не вирішують актуального питання.
Вай Ха Лі

Я вважаю, що це проблема Unicode, яку FINDSTR не підтримує. Перенаправлення CMD.EXE може належним чином відкрити ім'я файлу з unicode, як і команда TYPE. Але десь уздовж лінії FINDSTR перетворює і en-dash, і em-dash у звичайний тире, і звичайно ОС не може знайти це ім'я. Якщо ви створюєте інший файл, що замінює тире для en-dash та / або em-dash, то FINDSTR шукатиме файл тире, якщо він надається ім'ям, що містить en-dash або em-dash.
dbenham

Я б класифікував це питання як обмеження, а не помилку.
dbenham

Насправді, це не стільки проблема Unicode, скільки розширена ASCII. Я вже задокументував це питання у своїй оригінальній відповіді під заголовком Обмеження символів для параметрів командного рядка - Розширене перетворення ASCII . FINDSTR перетворює ряд розширених кодів ASCII у "пов'язані" справжні ASCII, включаючи en-dash та em-dash.
dbenham

1

findstrКоманда встановлює ErrorLevel(або код виходу) до одного з наступних значень, враховуючи , що немає ніяких недійсних або несумісних вимикачів і не рядок пошуку не перевищує граничне значення довжини:

  • 0 коли принаймні одна відповідність зустрічається в одному рядку протягом усіх вказаних файлів;
  • 1 інакше;

Вважається, що рядок містить відповідність, коли:

  • не /Vзадано жодної опції, а пошуковий вираз виникає принаймні один раз;
  • /Vзадана опція і вираз пошуку не відбувається;

Це означає, що /Vопція також змінює повернутий ErrorLevel, але він не просто поверне його!

Наприклад, якщо у вас є файл test.txtз двома лініями, одна з яких містить рядок , textа інший ні, як findstr "text" "test.txt"і findstr /V "text" "test.txt"повертати ErrorLevelз 0.

В основному ви можете сказати: якщо findstrповертає принаймні рядок, ErrorLevelвстановлено значення 0, інше - 1.

Зауважте, що /Mпараметр не впливає на ErrorLevelзначення, він просто змінює вихід.

(Тільки задля повноти: findкоманда поводиться точно так само стосовно /Vпараметра і ErrorLevel; /Cопція не впливає ErrorLevel.)


1

У FINDSTR є кольорова помилка, яку я описав та вирішив на /superuser/1535810/is-there-a-better-way-to-mitigate-this-obscure-color-bug-when-piping-to -findstr / 1538802? noredirect = 1 # comment2339443_1538802

Підсумовуючи цей потік, помилка полягає в тому, що якщо вхід передається на FINDSTR в межах круглого блоку коду, вбудовані кольорові коди ANSI перестають працювати в командах, виконаних пізніше. Прикладом вбудованих кольорових кодів є: echo %magenta%Alert: Something bad happened%yellow%(де пурпурний та жовтий - параметри, визначені раніше у файлі .bat як відповідні кольорові коди відходу ANSI).

Моє початкове рішення - викликати підпрограму "нічого робити" після FINDSTR. Якось виклик або повернення "скидає" все, що потрібно скинути.

Пізніше я виявив ще одне рішення, яке, мабуть, є більш ефективним: помістіть фразу FINDSTR в круглі дужки, як у наступному прикладі: echo success | ( FINDSTR /R success ) Якщо розміщення фрази FINDSTR у вкладеному блоці коду, схоже, виділить помилку кольорового коду FINDSTR, щоб це не вплинуло на те, що знаходиться поза вкладеним блок. Можливо, ця методика вирішить і деякі інші небажані побічні ефекти FINDSTR .


Чудова знахідка. Але ваші правила можна спростити (принаймні, на моїй службовій машині Windows 10). FINDSTR забороняє всі послідовності втечі консолі працювати для наступних команд у межах одного блоку команд. Не має значення, чи FINDSTR читає трубку, перенаправлений вхід або файл. Невдача послідовності втечі не обмежується кольоровими кодами. Командний блок - це будь-який набір команд в дужках та / або команди, об'єднані через &, && або || або ||
dbenham

@dbenham: Приємне узагальнення проблеми. Чи знаєте ви, чи моє рішення - введення фрази FINDSTR всередині дужок - працює і в загальному випадку? А чи знаєте ви, чи має мій розчин якісь небажані побічні ефекти?
Долорес Стівенс

Я не робив вичерпного тестування, але так, вкладені дужки здаються загальним рішенням, і я не можу придумати жодних можливих небажаних побічних ефектів.
dbenham

-1

Порада / D для декількох каталогів: поставте список каталогу перед рядком пошуку. Ці всі працюють:

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

Як очікувалося, шлях відносно місця розташування, якщо ви не запускаєте каталоги \. Оточення шляху шляхом "необов’язкове, якщо в іменах каталогу немає пробілів. Закінчення \необов’язкове. Вихід з розташування буде включати незалежний шлях. Він буде працювати з або без оточення списку каталогів ".


Я не бачу тут нічого недокументованого. Параметр / D описаний у вбудованій довідці. Це не питання для загальних порад щодо використання FINDSTR. Він суворо призначений для переліку недокументованих функцій, обмежень та / або помилок.
dbenham

1
@dbenham правда, це не справді недокументовано, але я виявив, що мені довелося задекларувати findstr, щоб отримати потрібні результати, і я ділюся тим, що знайшов роботу DID, щоб люди не витрачали час на експерименти з командами, які НЕ працюють. hth (мені сумно, що ти не любиш мою інформацію - вона мала бути лише конструктивною)
gordon

Перемикач IMHO / D чітко описаний у вбудованій довідці: /D:dirlist Search a semicolon-delimited list of directoriesі він розміщується перед рядком пошуку, тому я не розумію, що саме "ви знайшли" про перемикач / D (і що таке "команди, які НЕ працюйте ") ...
Аакіні

@Aacini у багатьох мовах порядок атрибутів значення не має. Я findstrспершу розумію документацію для списків / D. Так, я не маю аргументів з тим, що функція документально зафіксована, це просто не задокументоване питання про те, що порядок атрибутів має значення. Я дуже мало працюю з командним рядком, тому, коли я перебирав команду, не усвідомлюючи, що порядок змінився, я просто додавав атрибути, коли я дістався до них (і за алфавітом, С передує D). Я був дуже розчарований і поділився своїм «знайденим» досвідом для всіх, хто не дуже працює з командним рядком.
Гордон

1
Порядок необов'язкових атрибутів зазвичай не має значення. У findstrдокументації вказано, що stringsчастина НЕ є необов'язковою, і ви повинні розмістити її після необов'язкових атрибутів та перед необов'язковим списком імен файлів. Якщо "ваш знайдений" полягає в тому, що використання команди без дотримання її формату використання викликає помилку, то такий пункт добре задокументований. Див. Синтаксис команд : "Синтаксис відображається в тому порядку, в якому потрібно ввести команду та будь-які параметри, які слідують за нею"
Aacini
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.