Как условно принять меры, если FINDSTR не может найти строку

У меня есть пакетный файл следующего содержания;

CD C:\MyFolder
findstr /c:"stringToCheck" fileToCheck.bat
IF NOT XCOPY "C:\OtherFolder\fileToCheck.bat" "C:\MyFolder" /s /y

Я получаю сообщение об ошибке ("C: \ OtherFolder \ fileToCheck.bat" был неожиданным в это время.) При попытке выполнить это.

Пожалуйста, дайте мне знать, что я делаю не так.

26
задан Ross Ridge 17 February 2019 в 02:10
поделиться

4 ответа

Вы не оцениваете условие для IF. Я предполагаю, что вы не хотите копировать, если вы найдете stringToCheck в fileToCheck. Вам нужно сделать что-то вроде (код не проверен, но вы поняли идею):

CD C:\MyFolder
findstr /c:"stringToCheck" fileToCheck.bat
IF NOT ERRORLEVEL 0 XCOPY "C:\OtherFolder\fileToCheck.bat" "C:\MyFolder" /s /y

РЕДАКТИРОВАТЬ по dbenham
Вышеупомянутый тест НЕПРАВИЛЬНЫЙ, он всегда оценивается как ЛОЖЬ.
Правильный тест - IF ERRORLEVEL 1 XCOPY ...

Обновление: я не могу проверить код, но я не уверен, какое возвращаемое значение возвращает findstr, если ничего не находит. Возможно, вам придется сделать что-то вроде:

CD C:\MyFolder
findstr /c:"stringToCheck" fileToCheck.bat > tempfindoutput.txt
set /p FINDOUTPUT= < tempfindoutput.txt
IF "%FINDOUTPUT%"=="" XCOPY "C:\OtherFolder\fileToCheck.bat" "C:\MyFolder" /s /y
del tempfindoutput.txt
11
ответ дан 28 November 2019 в 06:15
поделиться

Я предполагаю, что вы хотите скопировать C: \ OtherFolder \ fileToCheck.bat в C: \ MyFolder, если существующий файл в C: \ MyFolder либо полностью отсутствует, либо если отсутствует "stringToCheck".

FINDSTR устанавливает ERRORLEVEL в 0, если строка найдена, в 1, если это не так. Он также устанавливает errorlevel на 1, если файл отсутствует. Он также распечатывает каждую строку, которая соответствует. Поскольку вы пытаетесь использовать его как условие, я полагаю, что вам не нужно или вы не хотите видеть какие-либо результаты. Первое, что я хотел бы предложить, это перенаправить как нормальный, так и вывод ошибок на nul, используя >nul 2>&1.

Решение 1 (в основном то же, что и предыдущие ответы)

Вы можете использовать IF ERRORRLEVEL N, чтобы проверить, является ли уровень ошибки> = N. Или вы можете использовать IF NOT ERRORLEVEL N, чтобы проверить если уровень ошибки равен < N. В твоем случае ты хочешь первое.

findstr /c:"stringToCheck" "c:\MyFolder\fileToCheck.bat" >nul 2>&1
if errorlevel 1 xcopy "C:\OtherFolder\fileToCheck.bat" "c:\MyFolder"

Решение 2

Вы можете проверить определенное значение уровня ошибки, используя% ERRORLEVEL%. Вероятно, вы можете проверить, равно ли значение 1, но может быть безопаснее проверить, не равно ли оно значению 0, поскольку оно установлено на 0, только если файл существует и содержит строку.

findstr /c:"stringToCheck" "c:\MyFolder\fileToCheck.bat" >nul 2>&1
if not %errorlevel% == 0 xcopy "C:\OtherFolder\fileToCheck.bat" "c:\MyFolder"

или

findstr /c:"stringToCheck" "c:\MyFolder\fileToCheck.bat" >nul 2>&1
if %errorlevel% neq 0 xcopy "C:\OtherFolder\fileToCheck.bat" "c:\MyFolder"

Решение 3

Существует очень компактный синтаксис для условного выполнения команды на основе успеха или неудачи предыдущего команда: cmd1 && cmd2 || cmd3, что означает выполнение cmd2, если cmd1 был успешным (errorlevel = 0), иначе выполнить cmd3, если cmd1 не удалось (errorlevel <> 0). Вы можете использовать & amp; один или || в одиночестве. Все команды должны быть в одной строке. Если вам нужно условно выполнить несколько команд, вы можете использовать несколько строк, добавив скобки

cmd1 && (
   cmd2
   cmd3
) || (
   cmd4
   cmd5
)

Так что для вашего случая все, что вам нужно, это

findstr /c:"stringToCheck" "c:\MyFolder\fileToCheck.bat" >nul 2>&1 || xcopy "C:\OtherFolder\fileToCheck.bat" "c:\MyFolder"

Но будьте осторожны - || ответит на код возврата последней выполненной команды. В моем предыдущем псевдокоде ||, очевидно, сработает, если cmd1 завершится неудачно, но также сработает, если cmd1 будет успешным, но затем cmd3 завершится неудачей.

Так что, если ваш успешный блок заканчивается командой, которая может потерпеть неудачу, тогда вы должны добавить безвредную команду, которая гарантированно завершится успешно. Мне нравится использовать (CALL ), который безвреден и всегда успешен. Также удобно, что он устанавливает ERRORLEVEL в 0. Существует следствие (CALL), которое всегда терпит неудачу и устанавливает ERRORLEVEL в 1.

66
ответ дан 28 November 2019 в 06:15
поделиться

В DOS / Windows Batch большинство команд возвращают код выхода, называемый «errorlevel», то есть значение, которое обычно равно нулю, если команда заканчивается правильно, или числу больше нуля, если оно заканчивается из-за ошибки, с большими числами для больших ошибок (отсюда и название).

Существует несколько методов для проверки этого значения, но оригинальным является:

IF ERRORLEVEL value command

Предыдущий тест IF, если уровень ошибки, возвращенный предыдущей командой, был БОЛЬШЕ, ЧЕМ ИЛИ РАВНЫМ заданным значением, и, если это правда, выполните команду. Например:

verify bad-param
if errorlevel 1 echo Errorlevel is greater than or equal 1
echo The value of errorlevel is: %ERRORLEVEL%

Команда Findstr возвращает 0, если строка была найдена, и 1, если нет:

CD C:\MyFolder
findstr /c:"stringToCheck" fileToCheck.bat
IF ERRORLEVEL 1 XCOPY "C:\OtherFolder\fileToCheck.bat" "C:\MyFolder" /s /y

Предыдущий код будет копировать файл, если строка НЕ ​​была найдена в файле .

CD C:\MyFolder
findstr /c:"stringToCheck" fileToCheck.bat
IF NOT ERRORLEVEL 1 XCOPY "C:\OtherFolder\fileToCheck.bat" "C:\MyFolder" /s /y

Предыдущий код скопировать файл, если строка была найдена. Попробуйте это:

findstr "string" file
if errorlevel 1 (
    echo String NOT found...
) else (
    echo String found
)
5
ответ дан 28 November 2019 в 06:15
поделиться

Я пытался заставить это работать, используя FINDSTR, но по какой-то причине моя команда «отладки» всегда выводила уровень ошибки 0:

ECHO %ERRORLEVEL%

Мой обходной путь - использовать Grep из Cygwin, который выводит правильный уровень ошибки (он даст уровень ошибки больше 0), если строка не найдена:

dir c:\*.tib >out 2>>&1
grep "1 File(s)" out
IF %ERRORLEVEL% NEQ 0 "Run other commands" ELSE "Run Errorlevel 0 commands"

Программа Cygwin grep также выведет уровень ошибки 2, если файл не найден. Вот хеш из моей версии:

C: \ temp \ temp> grep - версия grep (GNU grep) 2.4.2

C: \ cygwin64 \ bin> md5sum grep.exe c0a50e9c731955628ab66235d10cea23 * grep.exe

C: \ cygwin64 \ bin> sha1sum grep.exe ff43a335bbec71cfe99ce8d5cb4e7c1ecdb3db5c * grep.exe

0
ответ дан 28 November 2019 в 06:15
поделиться