243 votes

Fichier batch : Trouver si la sous-chaîne est dans une chaîne de caractères (pas dans un fichier)

Dans un fichier batch, j'ai une chaîne abcdefg . Je veux vérifier si bcd est dans la chaîne.

Malheureusement, il semble que toutes les solutions que j'ai trouvées cherchent un fichier pour une sous-chaîne, et non une chaîne pour une sous-chaîne.

Existe-t-il une solution simple pour cela ?

7 votes

D'habitude, c'est soit Windows y cmd o c'est ms-dos . MSDOS ne fait plus partie de Windows depuis un an. long temps.

328voto

paxdiablo Points 341644

Oui, vous pouvez utiliser des substitutions et les vérifier par rapport à la chaîne originale :

if not x%str1:bcd=%==x%str1% echo It contains bcd

El %str1:bcd=% remplacera un bcd sur str1 avec une chaîne vide, ce qui la rend différente de l'original.

Si l'original ne contenait pas de bcd dans celle-ci, la version modifiée sera identique.

Un test avec le script suivant le montrera en action :

@setlocal enableextensions enabledelayedexpansion
@echo off
set str1=%1
if not x%str1:bcd=%==x%str1% echo It contains bcd
endlocal

Et les résultats des différents parcours :

c:\testarea> testprog hello

c:\testarea> testprog abcdef
It contains bcd

c:\testarea> testprog bcd
It contains bcd

Quelques notes :

  • El if La déclaration est le cœur de cette solution, tout le reste n'est que du support.
  • El x avant les deux côtés de l'égalité est de s'assurer que la ficelle bcd fonctionne bien. Il protège également contre certains caractères de départ "incorrects".

7 votes

Si vous cherchez comment faire un remplacement de chaîne dans une boucle FOR : stackoverflow.com/a/6310580/623622

75 votes

C'est très bien, mais j'ai eu du mal à le faire fonctionner lorsque la valeur recherchée n'était pas une constante (comme bcd) mais une variable. Après beaucoup de temps, j'ai finalement trouvé la solution. En supposant que searchVal a été déclaré, "x!str1:%searchVal%= !"=="x%str1%"

9 votes

@Gary, puisque ce n'était pas l'une des exigences de cette question, vous auriez probablement dû poser une autre question, peut-être en faisant un lien vers celle-ci comme référence. Il n'y a pas de pénurie de personnes prêtes à aider. En fait, vous devriez tout de même poser cette question et y répondre vous-même (maintenant que vous avez trouvé la réponse) afin qu'elle soit utile aux futurs chercheurs. L'auto-réponse est considérée comme acceptable.

117voto

ghostdog74 Points 86060

Vous pouvez envoyer la chaîne source vers findstr et vérifier la valeur de ERRORLEVEL pour voir si la chaîne de caractères du motif a été trouvée. Une valeur de zéro indique un succès et que le motif a été trouvé. Voici un exemple :

::
: Y.CMD - Test if pattern in string
: P1 - the pattern
: P2 - the string to check
::
@echo off

echo.%2 | findstr /C:"%1" 1>nul

if errorlevel 1 (
  echo. got one - pattern not found
) ELSE (
  echo. got zero - found pattern
)

Quand on l'exécute dans CMD.EXE, on obtient :

C:\DemoDev>y pqrs "abc def pqr 123"
 got one - pattern not found

C:\DemoDev>y pqr "abc def pqr 123" 
 got zero - found pattern

0 votes

"FINDSTR : Argument manquant après /C. En a obtenu un - motif non trouvé"

0 votes

J'ai pu facilement le faire fonctionner dans une boucle for, aussi. Je n'ai pas pu retravailler la réponse acceptée pour une boucle for (bien que je n'aie pas essayé de voir pourquoi cela ne fonctionnait pas).

0 votes

Cette solution est très facile à lire. Je recommande de vérifier cette autre réponse pour quelques écueils.

56voto

user839791 Points 76

Je fais habituellement quelque chose comme ça :

Echo.%1 | findstr /C:"%2">nul && (
    REM TRUE
) || (
    REM FALSE
)

Exemple :

Echo.Hello world | findstr /C:"world">nul && (
    Echo.TRUE
) || (
    Echo.FALSE
)

Echo.Hello world | findstr /C:"World">nul && (Echo.TRUE) || (Echo.FALSE)

Sortie :

TRUE
FALSE

Je ne sais pas si c'est le meilleur moyen.

0 votes

J'avais besoin de trouver et de comparer récursivement des noms de fichiers. C'est la seule solution qui a fonctionné pour moi aussi ! Super pratique et très simple.

29voto

Ben Personick Points 1

Pour des raisons de compatibilité et de facilité d'utilisation, il est souvent préférable d'utiliser FIND pour ce faire.

Vous devez également considérer si vous souhaitez faire correspondre les cas sensibles ou les cas insensibles.

La méthode avec 78 points (je crois que je faisais référence au post de paxdiablo) ne correspondra que de manière sensible à la casse, donc vous devez mettre une vérification séparée pour chaque variation de casse pour chaque itération possible que vous voulez correspondre.

( Quelle douleur ! Avec seulement 3 lettres, cela signifie 9 tests différents afin d'accomplir le contrôle ! )

En outre, il est souvent préférable de faire correspondre la sortie de commande, une variable dans une boucle ou la valeur d'une variable pointeur dans votre batch/CMD, ce qui n'est pas aussi simple.

Pour ces raisons, il s'agit d'une méthodologie alternative préférable :

Utiliser : Trouver [/I] [/V] "Caractères à faire correspondre".

[/I] (insensible à la casse) [/V] (Ne doit PAS contenir les caractères)

En tant que ligne unique :

ECHO.%Variable% | FIND /I "ABC">Nul && ( Echo.Found "ABC" ) || ( Echo.Did not find "ABC" )

Multi-ligne :

ECHO.%Variable%| FIND /I "ABC">Nul && ( 
  Echo.Found "ABC"
) || (
  Echo.Did not find "ABC"
)

Comme nous l'avons mentionné, cette méthode est idéale pour les éléments qui ne sont pas dans des variables qui permettent également la substitution de chaînes de caractères :

FOR %A IN (
  "Some long string with Spaces does not contain the expected string"
  oihu AljB
  lojkAbCk
  Something_Else
 "Going to evaluate this entire string for ABC as well!"
) DO (
  ECHO.%~A| FIND /I "ABC">Nul && (
    Echo.Found "ABC" in "%A"
  ) || ( Echo.Did not find "ABC" )
)

Output From a command:

    NLTest | FIND /I "ABC">Nul && ( Echo.Found "ABC" ) || ( Echo.Did not find "ABC" )

As you can see this is the superior way to handle the check for multiple reasons.

0 votes

Pour le problème de la sensibilité à la casse, vous pouvez utiliser setlocal EnableExtensions puis IF /I pour effectuer des comparaisons sans tenir compte de la casse.

1 votes

Ce n'est pas vraiment une option parce que vous auriez toujours besoin d'isoler les caractères pour une comparaison "IF". IF ne correspondra pas en termes "similaires" à ce que le PO et les solutions particulières auxquelles j'ai répondu recherchent..,

2 votes

Bonjour Ben, Veuillez ne pas faire référence aux autres réponses par le nombre de points qu'elles ont. Cela risque de changer. Veuillez mettre à jour votre réponse en faisant référence à l'autre réponse par le nom de l'auteur de cette réponse, ou par une brève phrase décrivant la technique utilisée dans cette réponse.

12voto

byorking Points 127

Si vous détectez une présence, voici la solution la plus simple :

SET STRING=F00BAH
SET SUBSTRING=F00
ECHO %STRING% | FINDSTR /C:"%SUBSTRING%" >nul & IF ERRORLEVEL 1 (ECHO CASE TRUE) else (ECHO CASE FALSE)

Cela fonctionne très bien pour déposer la sortie des commandes Windows dans une variable booléenne. Remplacez simplement l'écho par la commande que vous souhaitez exécuter. Vous pouvez également enchaîner les Findstr ensemble pour qualifier davantage une déclaration en utilisant les pipes. Par exemple, pour Service Control (SC.exe)

SC QUERY WUAUSERV | findstr /C:"STATE" | FINDSTR /C:"RUNNING" & IF ERRORLEVEL 1 (ECHO case True) else (ECHO CASE FALSE)

Celui-ci évalue la sortie de SC Query pour les services de mise à jour de Windows, qui se présente sous la forme d'un texte multiligne, trouve la ligne contenant "state", puis vérifie si le mot "running" apparaît sur cette ligne, et définit le niveau d'erreur en conséquence.

8 votes

Vous avez votre déclaration IF à l'envers Tu regardes l'original avec abcdefg et tu fais basculer ta logique. Ça marche. De la façon dont tu l'as fait, ça ne marche pas. SET STRING=abcdefgh SET SUBSTRING=bcd ECHO %STRING% | FINDSTR /C:"%SUBSTRING%" >nul & IF ERRORLEVEL 1 (ECHO CASE FALSE) else (ECHO CASE TRUE)

2 votes

Un +1 est dû même si @Leptonator a raison avec la logique inversée. Il s'agit d'une solution simple et facile à utiliser.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X