バッチファイル:部分文字列が文字列内にある(ファイル内にない)かどうかを確認します


208

バッチファイルに文字列がありますabcdefgbcd文字列に含まれているかどうかを確認したい。

残念ながら、私が見つけているすべての解決策は、部分文字列の文字列ではなく、部分文字列のファイルを検索しているようです

これに対する簡単な解決策はありますか?


5
ところで、それはどちらか通常だWindowscmd 、それですms-dos。MSDOSは長い間 Windowsの一部ではありませんでした。
paxdiablo 2011

回答:


288

はい、置換を使用して、元の文字列と照合できます。

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

%str1:bcd=%ビットが置き換えられますbcdstr1、元からそれは違う作り、空の文字列を持ちます。

オリジナルにbcd文字列が含まれていない場合、変更されたバージョンは同一になります。

次のスクリプトでテストすると、実際の動作がわかります。

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

そして、さまざまな実行の結果:

c:\testarea> testprog hello

c:\testarea> testprog abcdef
It contains bcd

c:\testarea> testprog bcd
It contains bcd

いくつかのメモ:

  • if声明は、このソリューションの肉で、他のすべては、サポートスタッフです。
  • x平等の両側の前は、文字列が正常に機能することを確認することbcdです。また、特定の「不適切な」開始文字から保護します。

7
FORループで文字列を置換する方法を検討している場合:stackoverflow.com/a/6310580/623622
Czarek Tomczak '22

60
これはすばらしいことですが、検索値が(bcdのように)定数ではなく変数である場合に、これを機能させるのに苦労しました。しばらくして、ようやくそれを理解しました。searchValが宣言されていると仮定すると、「x!str1:%searchVal%=!」== "x%str1%"
Gary Brunton

7
@Gary、それはこの質問の要件の1つではなかったので、おそらく別の質問をする必要があったでしょう。おそらく、参照としてこの質問にリンクを張ってください。手伝ってくれる人がたくさんいます。実際、あなたはまだその質問をして自分で答えるべきです(あなたがそれを理解したので)ので、将来の検索者に役立つでしょう。自己回答は許容範囲と見なされます。
paxdiablo 2013

6
非常に良い解決策ですが、二重引用符で囲む必要があります。そうしないと、値にスペースが含まれる変数では機能しません。例:if "not%xstr1:bcd =%" == "x%str1%" echo It BCDを含む
Helge Klein、

4
"'= str1は現時点では予期されていなかった"
Berit Larsen

104

ソース文字列をパイプしてfindstrの値をチェックしERRORLEVEL、パターン文字列が見つかったかどうかを確認できます。ゼロの値は成功を示し、パターンが見つかりました。次に例を示します。

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

これをCMD.EXEで実行すると、次のようになります。

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

「FINDSTR:/ Cの後に引数がありません。取得しました-パターンが見つかりません」
Berit Larsen

47

私は通常次のようなことをします:

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

例:

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

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

出力:

TRUE
FALSE

これが最善の方法かどうかはわかりません。


ファイル名を再帰的に検索して比較する必要がありました。これも私にとって有効な唯一の解決策でした!超便利でとてもシンプル。
サージェームズ2017年

24

互換性と使いやすさのために、これを行うにはFINDを使用する方が良い場合がよくあります。

大文字と小文字を区別して大文字と小文字を区別するかどうかも考慮する必要があります。

78ポイントの方法(paxdiabloの投稿を参照していたと思います)は大文字と小文字を区別してのみ一致するため、一致する可能性のあるすべての反復について、ケースのバリエーションごとに個別のチェックを行う必要があります。

(なんて面倒なことだろう。たった3文字で、チェックを完了するために9つの異なるテストを意味する!)

さらに、多くの場合、コマンド出力、ループ内の変数、またはバッチ/ CMD内のポインター変数の値を一致させることは、それほど単純ではありません。

これらの理由により、これは望ましい代替方法です。

使用:検索[/ I] [/ V]「一致する文字」

[/ I](大文字と小文字を区別しない)[/ V](文字を含めないでください)

単一行として:

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

複数行:

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

言及したように、これは文字列の置換を許可する変数にないものに最適です:

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.

大文字と小文字の区別の問題については、setlocal EnableExtensionsthen IF /Iを使用して大文字と小文字を区別しない比較を行うことができます。
サイチョイ2014年

1
「IF」比較のために文字を分離する必要があるため、これは実際にはオプションではありません。OPと私が返信した特定のソリューションが探しているため、「いいね」の条件で一致しない場合
Ben Benick

こんにちは、ベン、他の回答はポイント数で参照しないでください。それは変わる可能性があります。他の回答を参照して回答を更新し、その回答の作成者名、またはその回答で使用されている手法を説明する短いフレーズを使用してください。
phonetagger

こんにちは、Phone Taggerです。3年前に元の投稿を書いたときに役立つコメントでしたが、ポイントの値はすべて変更されました。私はどの投稿を参照していたのかもう覚えていません。今日のポイント値でそれらを参照することはありません。とにかくありがとう。
Ben Personick 2017

私は周りを見回し、paxdiabloを指していたと思うので、それを示すためにテキストを修正しました。
Ben Personick 2017

10

存在を検出している場合、最も簡単な解決策は次のとおりです。

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

これは、Windowsコマンドの出力をブール変数にドロップするのに最適です。エコーを実行したいコマンドに置き換えるだけです。Findstrの文字列を組み合わせて、パイプを使用してステートメントをさらに修飾することもできます。EG for Service Control(SC.exe)

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

これは、複数行のテキストとして出力されるWindows UpdateサービスのSCクエリの出力を評価し、「state」を含む行を見つけて、その行に「running」という単語が含まれているかどうかを確認し、それに応じてエラーレベルを設定します。


6
IFステートメントが逆方向にあります。abcdefgでオリジナルを見て、ロジックをフリップフロップします。できます。あなたのやり方はそうではありません。SET STRING=abcdefgh SET SUBSTRING=bcd ECHO %STRING% | FINDSTR /C:"%SUBSTRING%" >nul & IF ERRORLEVEL 1 (ECHO CASE FALSE) else (ECHO CASE TRUE)
Leptonator 2015

2
@Leptonatorが反転論理で正しいにもかかわらず、+ 1が原因です。これはシンプルで使いやすいソリューションです。
Laryx Decidua 2015年

2

私はおそらくこの回答で少し遅すぎますが、受け入れられた回答は、「ハードコードされた文字列」が検索文字列の一部であるかどうかを確認するためにのみ機能します。

動的検索の場合、これを行う必要があります。

SET searchString=abcd1234
SET key=cd123

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

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

注:2つの変数を引数として取ることができます。


1

より良い答えがここにありました

set "i=hello " world"
set i|find """" >nul && echo contains || echo not_contains

SETを使用してリンクする質問は、特定の固有のニーズを解決するため、「SET」について言及することが重要です。ただし、FINDコマンドにコマンドをパイプして結果をテストする方法はすでに提供されているため、現在の説明には何も追加されていないようです
Ben Personick


0

検索ソリューションファイルをサブのためにも、検索することができ、文字列、例えば。findまたはfindstr
あなたの場合、簡単な解決策は、ファイル名を指定する代わりにコマンドに文字列をパイプすることです。

大文字と小文字を区別する文字列:
echo "abcdefg" | find "bcd"

文字列の大文字と小文字を区別しない:
echo "abcdefg" | find /I "bcd"

一致が見つからない場合、CMDで空白行の応答が返され、%ERRORLEVEL%が1に設定されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.