如果FINDSTR无法找到字符串,如何有条件地采取措施

tes*_*dtv 26 windows cmd batch-file

我有一个批处理文件如下;

CD C:\MyFolder
findstr /c:"stringToCheck" fileToCheck.bat
IF NOT XCOPY "C:\OtherFolder\fileToCheck.bat" "C:\MyFolder" /s /y
Run Code Online (Sandbox Code Playgroud)

我收到一个错误("C:\ OtherFolder\fileToCheck.bat"此时出乎意料.)尝试执行此操作时.

请让我知道我做错了什么.

dbe*_*ham 66

我想你要复制C:\ OtherFolder\fileToCheck.bat到C:\ MyFolder文件,如果在C现有文件:\ MyFolder文件要么完全丢失,或者如果它丢失"stringToCheck".

如果找到字符串,FINDSTR将ERRORLEVEL设置为0,否则设置为1.如果文件丢失,它还将errorlevel设置为1.它还打印出匹配的每一行.由于您尝试将其用作条件,我认为您不需要或不想看到任何输出.我建议的第一件事是将正常和错误输出重定向到nul使用>nul 2>&1.

解决方案1(与以前的答案大致相同)

你可以IF ERRORRLEVEL N用来检查errorlevel是否> = N.或者你可以IF NOT ERRORLEVEL N用来检查errorlevel是否<N.在你的情况下你想要前者.

findstr /c:"stringToCheck" "c:\MyFolder\fileToCheck.bat" >nul 2>&1
if errorlevel 1 xcopy "C:\OtherFolder\fileToCheck.bat" "c:\MyFolder"
Run Code Online (Sandbox Code Playgroud)

解决方案2

您可以使用%ERRORLEVEL%测试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"
Run Code Online (Sandbox Code Playgroud)

要么

findstr /c:"stringToCheck" "c:\MyFolder\fileToCheck.bat" >nul 2>&1
if %errorlevel% neq 0 xcopy "C:\OtherFolder\fileToCheck.bat" "c:\MyFolder"
Run Code Online (Sandbox Code Playgroud)

解决方案3

有一个很紧凑语法有条件地执行基于先前命令的成功或失败的命令:cmd1 && cmd2 || cmd3这意味着执行CMD2如果CMD1成功(错误级别= 0),否则执行CMD3如果CMD1失败(错误级别<> 0).您可以单独使用&&或|| 单独.所有命令都需要在同一行.如果需要有条件地执行多个命令,可以通过添加括号来使用多行

cmd1 && (
   cmd2
   cmd3
) || (
   cmd4
   cmd5
)
Run Code Online (Sandbox Code Playgroud)

所以对于你的情况,你需要的只是

findstr /c:"stringToCheck" "c:\MyFolder\fileToCheck.bat" >nul 2>&1 || xcopy "C:\OtherFolder\fileToCheck.bat" "c:\MyFolder"
Run Code Online (Sandbox Code Playgroud)

但要注意 - ||将响应最后执行的命令的返回码.在我之前的伪代码中,||如果cmd1失败,显然会触发,但如果cmd1成功但是cmd3失败,它也会触发.

因此,如果您的成功块以可能失败的命令结束,那么您应该附加一个保证成功的无害命令.我喜欢使用(CALL ),这是无害的,并且总是成功的.将ERRORLEVEL设置为0也很方便.有一个(CALL)总是失败的推论并将ERRORLEVEL设置为1.


Luk*_*Kim 11

您没有评估IF的条件.如果你在fileToCheck中找到stringToCheck,我猜想你不想复制.你需要做一些事情(代码未经测试,但你明白了):

CD C:\MyFolder
findstr /c:"stringToCheck" fileToCheck.bat
IF NOT ERRORLEVEL 0 XCOPY "C:\OtherFolder\fileToCheck.bat" "C:\MyFolder" /s /y
Run Code Online (Sandbox Code Playgroud)

由dbenham编辑
上面的测试是错误的,它总是评估为FALSE.
正确的测试是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
Run Code Online (Sandbox Code Playgroud)

  • ERRORLEVEL 检查的逻辑肯定是错误的。它的计算结果总是为 FALSE,因为 FINDSTR 总是以 ERRORLEVEL 0 或 1 退出,并且仅当 ERRORLEVEL 小于 0 时,“IF NOT ERRORLEVEL 0”才为 true。 (3认同)

Aac*_*ini 5

在DOS/Windows批处理中,大多数命令返回一个名为"errorlevel"的exitCode,如果命令正确结束,则该值通常等于零;如果因为错误而结束,则返回大于零的数字,错误越多,数字越大(由此得名).

有几种方法可以检查该值,但原始方法是:

IF ERRORLEVEL value command
Run Code Online (Sandbox Code Playgroud)

以前的IF测试,如果上一个命令返回的errorlevel大于或等于给定值,如果是,则执行命令.例如:

verify bad-param
if errorlevel 1 echo Errorlevel is greater than or equal 1
echo The value of errorlevel is: %ERRORLEVEL%
Run Code Online (Sandbox Code Playgroud)

如果找到字符串,则Findstr命令返回0,否则返回1:

CD C:\MyFolder
findstr /c:"stringToCheck" fileToCheck.bat
IF ERRORLEVEL 1 XCOPY "C:\OtherFolder\fileToCheck.bat" "C:\MyFolder" /s /y
Run Code Online (Sandbox Code Playgroud)

如果在文件中找不到该字符串,则以前的代码将复制该文件.

CD C:\MyFolder
findstr /c:"stringToCheck" fileToCheck.bat
IF NOT ERRORLEVEL 1 XCOPY "C:\OtherFolder\fileToCheck.bat" "C:\MyFolder" /s /y
Run Code Online (Sandbox Code Playgroud)

如果找到该字符串,则先前的代码将复制该文件.试试这个:

findstr "string" file
if errorlevel 1 (
    echo String NOT found...
) else (
    echo String found
)
Run Code Online (Sandbox Code Playgroud)