Comment agir conditionnellement si FINDSTR ne trouve pas une chaîne de caractères

j'ai un fichier de commandes comme suit:

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

je reçois une erreur ("C:OtherFolderfileToCheck.chauve-souris" était inattendu à cette époque.) en essayant d'exécuter ceci.

s'il vous Plaît laissez-moi savoir ce que je fais de mal.

21
demandé sur Bo Persson 2011-12-16 11:14:50

4 réponses

vous n'évaluez pas une condition pour le Fi. Je suppose que vous ne voulez pas copier si vous trouvez stringToCheck dans fileToCheck. Vous avez besoin de faire quelque chose comme (code non testé, mais vous voyez l'idée):

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

MODIFIER par dbenham

le test ci-dessus est erroné, il évalue toujours à faux.

Le bon test est IF ERRORLEVEL 1 XCOPY ...

mise à jour: Je ne peux pas tester le code, mais je ne suis pas sûr de la valeur de retour findstr revient s'il ne trouve rien. Vous pourriez avoir à faire quelque chose comme:

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
8
répondu Luke 2015-11-23 17:12:03

je présume que vous voulez copier C:\OtherFolder\fileToCheck.bat to C:\MyFolder si le fichier existant dans C:\MyFolder est totalement absent, ou s'il est manquant "stringToCheck".

FINDSTR définit ERRORLEVEL à 0 si la chaîne est trouvée, à 1 si elle ne l'est pas. Il définit également errorlevel 1 si le fichier est manquant. Il imprime aussi chaque ligne qui correspond. Puisque vous essayez de l'utiliser comme une condition, je présume que vous n'avez pas besoin ou envie de voir tout de la sortie. La 1ère chose que je voudrais suggérer est de rediriger la sortie normale et l'erreur à nul en utilisant >nul 2>&1.

Solution 1 (pour la plupart les mêmes que les réponses précédentes)

Vous pouvez utiliser IF ERRORRLEVEL N pour vérifier si le niveau d'erreur est >= N ou vous pouvez utiliser IF NOT ERRORLEVEL N pour vérifier si errorlevel est < N dans votre cas vous voulez le premier.

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

Solution 2

vous pouvez tester une valeur spécifique de errorlevel en utilisant %ERRORLEVEL%. Vous pouvez probablement vérifier si la valeur est égale à 1, mais il pourrait être plus sûr de vérifier si la valeur n'est pas égale à 0, car il est seulement mis à 0 si le fichier existe et qu'il contient la chaîne de caractères.

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

ou

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

Solution 3

il existe une syntaxe très compacte pour exécuter conditionnellement une commande basée sur le succès ou l'échec de la commande précédente:cmd1 && cmd2 || cmd3 ce qui signifie Exécuter cmd2 si cmd1 a réussi( errorlevel=0), sinon exécuter cmd3 si cmd1 a échoué (errorlevel<>0). Vous pouvez utiliser && seul, ou || seul. Toutes les commandes doivent être sur la même ligne. Si vous avez besoin pour exécuter conditionnellement plusieurs commandes vous pouvez utiliser plusieurs lignes en ajoutant des parenthèses

cmd 1 && (
   cmd2
   cmd3
) || (
   cmd4
   cmd5
)

alors pour votre cas, tout ce dont vous avez besoin est

findstr /c:"stringToCheck" "c:\MyFolder\fileToCheck.bat" >nul 2>&1 || xcopy "C:\OtherFolder\fileToCheck.bat" "c:\MyFolder"
62
répondu dbenham 2011-12-16 13:33:36

dans DOS/Windows Batch la plupart des commandes renvoient un exitCode, appelé "errorlevel", qui est une valeur qui est habituellement égale à zéro si la commande se termine correctement, ou un nombre supérieur à zéro si se termine parce qu'une erreur, avec des nombres plus grands pour des erreurs plus grandes (d'où le nom).

il y a quelques méthodes pour vérifier cette valeur, mais la première est:

IF ERRORLEVEL value command

test IF précédent si le niveau d'erreur retourné par la commande précédente était supérieur ou égal à donne la valeur et, si c'est vrai, exécute la commande. Par exemple:

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

commande Findstr renvoie 0 si la chaîne a été trouvée, et 1 sinon:

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

le code précédent copiera le fichier si la chaîne n'a pas été trouvée dans le fichier.

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

code précédent Copiez le fichier si la chaîne a été trouvée. Essayez ceci:

findstr "string" file
if errorlevel 1 (
    echo String NOT found...
) else (
    echo String found
)
5
répondu Aacini 2011-12-16 11:47:23

j'ai essayé de faire fonctionner cela en utilisant FINDSTR, mais pour une raison quelconque, ma commande "debugging" affiche toujours un niveau d'erreur de 0:

ECHO %ERRORLEVEL%

ma solution est D'utiliser Grep de Cygwin, qui affiche le niveau d'erreur droit (il donnera un niveau d'erreur supérieur à 0) si une chaîne n'est pas trouvée:

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

le grep de Cygwin affichera aussi errorlevel 2 si le fichier n'est pas trouvé. Voici le hash de ma version:

grep -- version grep (GNU grep)) 2.4.2

md5sum grep.EXE c0a50e9c731955628ab66235d10cea23 * grep.exe

sha1sum grep.EXE ff43a335bbec71cfe99ce8d5cb4e7c1のb3db5c * grep.exe

0
répondu Justin Goldberg 2015-02-09 17:17:41