Я предполагаю, что вы хотите скопировать 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
, чтобы проверить, равен ли уровень ошибок
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). Вы можете использовать && отдельно или || в одиночестве. Все команды должны быть в одной строке. Если вам нужно условно выполнить несколько команд, вы можете использовать несколько строк, добавив скобки
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.