Batch-Datei: Finden Sie heraus, ob sich die Teilzeichenfolge in einer Zeichenfolge befindet (nicht in einer Datei).

208

In einer Batch-Datei habe ich eine Zeichenfolge abcdefg. Ich möchte überprüfen, ob bcdin der Zeichenfolge.

Leider scheinen alle Lösungen, die ich finde, eine Datei nach einem Teilstring zu durchsuchen , nicht nach einem String für einen Teilstring.

Gibt es dafür eine einfache Lösung?

Ben
quelle
5
BTW, es ist in der Regel entweder Windowsund cmd oder es ist ms-dos. MS - DOS ist nicht Teil von Windows für eine seit langer Zeit.
Paxdiablo

Antworten:

288

Ja, Sie können Ersetzungen verwenden und mit der ursprünglichen Zeichenfolge vergleichen:

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

Das %str1:bcd=%Bit ersetzt ein bcdIn str1durch eine leere Zeichenfolge, wodurch es sich vom Original unterscheidet.

Wenn das Original keine bcdZeichenfolge enthält , ist die geänderte Version identisch.

Das Testen mit dem folgenden Skript zeigt es in Aktion:

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

Und die Ergebnisse verschiedener Läufe:

c:\testarea> testprog hello

c:\testarea> testprog abcdef
It contains bcd

c:\testarea> testprog bcd
It contains bcd

Ein paar Anmerkungen:

  • Die ifAussage ist das Fleisch dieser Lösung, alles andere ist Support.
  • Die xvor den beiden Seiten der Gleichung ist , um sicherzustellen , dass der String bcdfunktioniert in Ordnung. Es schützt auch vor bestimmten "falschen" Startzeichen.
paxdiablo
quelle
7
Wenn Sie wissen, wie Sie Zeichenfolgen in einer FOR-Schleife ersetzen können
Czarek Tomczak
60
Das ist großartig, aber ich hatte Mühe, dies zum Laufen zu bringen, wenn der Suchwert keine Konstante (wie bcd), sondern eine Variable war. Nach langer Zeit habe ich es endlich herausgefunden. Angenommen, searchVal wurde als "x! Str1:% searchVal% =!" == "x% str1%" deklariert
Gary Brunton
7
@ Gary, da dies keine der Anforderungen dieser Frage war, hätten Sie wahrscheinlich eine andere Frage stellen sollen, die möglicherweise als Referenz auf diese zurückführt. Es gibt keinen Mangel an Menschen, die bereit sind zu helfen. Tatsächlich sollten Sie diese Frage immer noch stellen und selbst beantworten (jetzt, wo Sie es herausgefunden haben), damit sie für zukünftige Suchende nützlich ist. Selbstantwort wird als akzeptabel angesehen.
Paxdiablo
6
Sehr gute Lösung, aber Sie müssen in doppelte Anführungszeichen setzen, sonst funktioniert es nicht mit Variablen, deren Werte Leerzeichen enthalten, z. B.: Wenn nicht "x% str1: bcd =%" == "x% str1%" echo It enthält bcd
Helge Klein
4
"'= str1 war zu diesem Zeitpunkt unerwartet"
Berit Larsen
104

Sie können die Quellzeichenfolge an weiterleiten findstr und den Wert von überprüfen, ERRORLEVELum festzustellen, ob die Musterzeichenfolge gefunden wurde. Ein Wert von Null zeigt Erfolg an und das Muster wurde gefunden. Hier ist ein Beispiel:

::
: 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
)

Wenn dies in CMD.EXE ausgeführt wird, erhalten wir:

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
Ghostdog74
quelle
"FINDSTR: Argument fehlt nach / C. Wurde eins - Muster nicht gefunden"
Berit Larsen
47

Normalerweise mache ich so etwas:

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

Beispiel:

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

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

Ausgabe:

TRUE
FALSE

Ich weiß nicht, ob das der beste Weg ist.

user839791
quelle
Ich musste rekursiv Dateinamen finden und vergleichen. Dies war die einzige Lösung, die auch für mich funktioniert hat! Super praktisch und sehr einfach.
SirJames
24

Aus Gründen der Kompatibilität und Benutzerfreundlichkeit ist es häufig besser, FIND zu verwenden, um dies zu tun.

Sie müssen auch überlegen, ob Sie den Fall sensibel oder den Fall unempfindlich abgleichen möchten.

Die Methode mit 78 Punkten (ich glaube, ich habe mich auf den Beitrag von paxdiablo bezogen) stimmt nur mit der Groß- und Kleinschreibung überein. Sie müssen daher für jede mögliche Iteration, die Sie möglicherweise abgleichen möchten, eine separate Prüfung für jede Fallvariation durchführen.

(Was für ein Schmerz! Bei nur 3 Buchstaben bedeutet das 9 verschiedene Tests, um die Prüfung durchzuführen!)

Darüber hinaus ist es häufig vorzuziehen, die Befehlsausgabe, eine Variable in einer Schleife oder den Wert einer Zeigervariablen in Ihrem Stapel / CMD abzugleichen, was nicht so einfach ist.

Aus diesen Gründen ist dies eine bevorzugte alternative Methode:

Verwenden Sie: Finden Sie [/ I] [/ V] "Übereinstimmende Zeichen"

[/ I] (Groß- und Kleinschreibung wird nicht berücksichtigt) [/ V] (Darf die Zeichen NICHT enthalten)

Als einzelne Zeile:

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

Mehrzeilig:

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

Wie bereits erwähnt, ist dies ideal für Dinge, die nicht in Variablen enthalten sind, die auch das Ersetzen von Zeichenfolgen ermöglichen:

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.
Ben Personick
quelle
Bei Problemen mit der Groß- und Kleinschreibung können Sie setlocal EnableExtensionsdann IF /IVergleiche ohne Berücksichtigung der Groß- und Kleinschreibung durchführen.
Cychoi
1
Dies ist keine Option, da Sie die Zeichen für einen "IF" -Vergleich noch isolieren müssten. WENN nicht in "Gefällt mir" -Begriffen übereinstimmen, da das OP und bestimmte Lösungen, auf die ich geantwortet habe, suchen.,
Ben Personick
Hallo Ben, bitte beziehen Sie sich nicht auf andere Antworten anhand der Anzahl der Punkte, die sie haben. Das wird sich wahrscheinlich ändern. Bitte aktualisieren Sie Ihre Antwort unter Bezugnahme auf die andere Antwort durch den Autorennamen dieser Antwort oder durch einen kurzen Satz, der die in dieser Antwort verwendete Technik beschreibt.
Phonetagger
Hallo Phone Tagger, das wäre vor drei Jahren ein hilfreicher Kommentar gewesen, als ich den ursprünglichen Beitrag geschrieben habe, aber wie Sie bereits erwähnt haben, haben sich alle Punktewerte geändert. Ich erinnere mich nicht mehr an den Beitrag, auf den ich mich bezog, und ich würde mich heute nicht mehr auf sie mit Punktwerten beziehen. Danke trotzdem.
Ben Personick
Ich habe mich umgesehen und glaube, ich habe mich auf paxdiablo bezogen, also habe ich den Text geändert, um das zu zeigen.
Ben Personick
10

Wenn Sie nach Präsenz suchen, ist dies die einfachste Lösung:

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

Dies funktioniert hervorragend, um die Ausgabe von Windows-Befehlen in eine boolesche Variable zu verschieben. Ersetzen Sie einfach das Echo durch den Befehl, den Sie ausführen möchten. Sie können Findstrs auch aneinanderreihen, um eine Anweisung mithilfe von Pipes weiter zu qualifizieren. EG für Servicesteuerung (SC.exe)

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

Dieser wertet die Ausgabe von SC Query für Windows Update Services aus, die als mehrzeiliger Text ausgegeben wird, findet die Zeile mit "state" und findet dann, ob das Wort "running" in dieser Zeile vorkommt, und legt die Fehlerstufe entsprechend fest.

byorking
quelle
6
Sie haben Ihre IF-Anweisung rückwärts. Wenn Sie das Original mit abcdefg betrachten, wird Ihre Logik umgedreht. Es klappt. So wie du es hast, tut es nicht. SET STRING=abcdefgh SET SUBSTRING=bcd ECHO %STRING% | FINDSTR /C:"%SUBSTRING%" >nul & IF ERRORLEVEL 1 (ECHO CASE FALSE) else (ECHO CASE TRUE)
Leptonator
2
Eine +1 ist fällig, obwohl @Leptonator mit der invertierten Logik korrekt ist. Dies ist eine einfache und benutzerfreundliche Lösung.
Laryx Decidua
2

Ich komme mit dieser Antwort wahrscheinlich etwas zu spät, aber die akzeptierte Antwort funktioniert nur, um zu überprüfen, ob eine "fest codierte Zeichenfolge" Teil der Suchzeichenfolge ist.

Für eine dynamische Suche müssten Sie Folgendes tun:

SET searchString=abcd1234
SET key=cd123

CALL SET keyRemoved=%%searchString:%key%=%%

IF NOT "x%keyRemoved%"=="x%searchString%" (
    ECHO Contains.
)

Hinweis: Sie können die beiden Variablen als Argumente verwenden.

Andy Sug
quelle
1

Bessere Antwort war hier :

set "i=hello " world"
set i|find """" >nul && echo contains || echo not_contains
T.Todua
quelle
In der Frage, die Sie mit SET verknüpfen, wird ein spezifischer und einzigartiger Bedarf gelöst. Daher ist es wichtig, "SET" zu erwähnen. Es scheint jedoch nichts zur aktuellen Diskussion hinzuzufügen, da die Methode zum Weiterleiten eines Befehls an den Befehl FIND und zum Testen des Ergebnisses bereits bereitgestellt ist
Ben Personick,
1
ECHO %String%| FINDSTR /C:"%Substring%" && (Instructions)
Riccardo La Marca
quelle
0

Die Lösungen, die eine Datei nach einem Teilstring durchsuchen , können auch einen String durchsuchen , z. findoder findstr.
In Ihrem Fall besteht die einfache Lösung darin, eine Zeichenfolge in den Befehl einzufügen, anstatt einen Dateinamen anzugeben, z.

Groß- und Kleinschreibung beachten:
echo "abcdefg" | find "bcd"

Zeichenfolge der Zeichenfolge ignorieren:
echo "abcdefg" | find /I "bcd"

Wenn keine Übereinstimmung gefunden wird, erhalten Sie eine leere Antwort auf CMD und% ERRORLEVEL% auf 1 gesetzt

Zimba
quelle