Пакетная команда для поиска числа появлений строки в файле - PullRequest
0 голосов
/ 22 апреля 2019

Мне нужно выяснить, сколько раз строка существует в файле. Если оно не равно 0, вернуть статус ошибки:

set "file=C:\output\summary.txt"
for /f %%F in (findstr /I "FAIL" %file% | find /I /C "FAIL") do (
    set count=%%F
)

if count neq 0 exit /B 1
exit /B 0

Но когда я запускаю пакет, я получаю ошибку:

| was unexpected at this time.

Как я могу исправить проблему и достичь ожидаемого?

Ответы [ 2 ]

1 голос
/ 22 апреля 2019

Похоже, что на самом деле не имеет значения, как часто искомая строка существует в файле. Похоже, вы хотите знать, только если файл содержит строку или нет. В этом случае достаточно оценить код завершения find.exe или findstr.exe, который может использоваться для поиска строки в файле. Оба выходят с 1, если не найдено совпадений для искомой строки, и с 0 хотя бы в одном найденном случае.

@echo off
%SystemRoot%\System32\findstr.exe /L /I /M /C:FAIL "C:\output\summary.txt" >nul
if errorlevel 1 exit /B 0
exit /B 1

То же, что и выше, как в одной командной строке с использованием условного выполнения:

@%SystemRoot%\System32\findstr.exe /L /I /M /C:FAIL "C:\output\summary.txt" >nul && exit /B 1 || exit /B 0

find.exe, выполненный с /C, выводит количество строк , содержащее искомую строку, которую можно присвоить переменной среды:

@echo off
set Count=
for /F "tokens=3 delims=:" %%I in ('%SystemRoot%\System32\find.exe /I /C "FAIL" "C:\output\summary.txt" 2^>nul') do set /A "Count=%%I"
if defined Count if %Count% == 0 exit /B 0
exit /B 1

set /A используется здесь, чтобы исключить пробел между : после вывода имени файла на find и количеством строк, содержащих искомую строку, один или несколько раз. Строка после set /A внутри двойных кавычек интерпретируется как арифметическое выражение, которое приводит к интерпретации пробела как разделителя и, следовательно, после преобразования числа, присвоенного переменной цикла I, с начальным пробелом из строки в целое число, число, назначенное без символ пробела назначается в качестве строки переменной среды Count.

Прочитайте статью Microsoft о Использование операторов перенаправления команд для объяснения 2>nul. Оператор перенаправления > должен быть экранирован с помощью символа вставки ^ в FOR командной строке, чтобы интерпретироваться как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , которая выполняет встроенную командную строку find в отдельном командном процессе, запущенном в фоновом режиме.

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

  • echo /?
  • exit /?
  • find /?
  • findstr /?
  • for /?
  • if /?
  • set /?

Предлагаю также прочитать:

Я настоятельно рекомендую не используя:

if %ERRORLEVEL% == 0
if %ERRORLEVEL% EQU 0
if "%ERRORLEVEL%" == "0"
if "%ERRORLEVEL%" EQU "0"

Почему?

Что ж, посмотрим, что происходит при встраивании такой оценки кода завершения в командный блок, как копирование и вставка в пакетный файл:

(
    set "file=C:\output\summary.txt"
    find /C "FAIL" %file%
    if "%ERRORLEVEL%"=="0" (
        exit /B 1
    ) else (
        exit /B 0
    )
)

Запустите этот пакетный файл из окна командной строки. Является ли результат правильным (случайно)? Да, запустите его еще раз без каких-либо изменений C:\output\summary.txt и командного файла. Теперь результат, как и прежде, противоположен, хотя ничего не изменилось. Посмотрите на строки, выводимые командным процессором Windows, и вы знаете, почему. %ERRORLEVEL% был заменен текущим значением ERRORLEVEL до того, как find был выполнен вообще, потому что cmd.exe всегда заменяет все ссылки на переменные среды с использованием синтаксиса %variable% при разборе всего блока команд перед выполнением любой команды, оставленной для блока команд или внутри блока команд.

0 голосов
/ 22 апреля 2019

Это кажется очень сложным, когда команда find делает то, что вам нужно (она устанавливает %ERRORLEVEL% в 1, если не находит строку):

set "file=C:\output\summary.txt"
find /C "FAIL" %file%
if "%ERRORLEVEL%"=="0" (
    exit /B 1
) else (
    exit /B 0
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...