批处理文件:查找子字符串是否在字符串中(不在文件中)


208

在批处理文件中,我有一个字符串abcdefg。我想检查是否bcd在字符串中。

不幸的是,似乎所有找到的解决方案都是在文件中搜索子字符串,而不是在字符串中搜索子字符串。

有一个简单的解决方案吗?


5
顺便说一句,它通常是要么Windowscmd 它的ms-dos。MSDOS一直没有对Windows的一部分的时间。
paxdiablo 2011年

Answers:


288

是的,您可以使用替换并检查原始字符串:

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

%str1:bcd=%位将用空字符串替换bcdin str1,使其与原始字符串不同。

如果原始文件中不包含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 2012年

60
很棒,但是当搜索值不是一个常量(如bcd)而是一个变量时,我很难使它起作用。经过很多时间,我终于弄明白了。假设searchVal已声明为“ x!str1:%searchVal%=!” ==“ x%str1%”
Gary Brunton 2013年

7
@Gary,因为这不是此问题的要求之一,所以您可能应该问一个不同的问题,也许可以将其链接回作为参考。不乏愿意提供帮助的人。实际上,您仍然应该问这个问题并自己回答(既然您已经解决了),这样对将来的搜索者将很有用。自回答被认为是可以接受的。
paxdiablo

6
很好的解决方案,但是您需要用双引号引起来,否则它的值中带有空格的变量将不起作用,例如:如果不是,则“ x%str1: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

我不知道这是否是最好的方法。


我需要递归查找和比较文件名。这也是唯一对我有用的解决方案!超级方便,非常简单。
詹姆士爵士(SirJames)'17年

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进行不区分大小写的比较。
cychoi 2014年

1
这并不是真正的选择,因为您仍然需要隔离字符以进行“ IF”比较。如果操作员和我答复的特定解决方案正在寻找,则如果在“赞”字词中无法匹配。,
Ben Personick

嗨,本,请不要以他们获得的分数来提及其他答案。这很可能会改变。请使用该答案的作者姓名或描述该答案中使用的技术的简短短语来更新参考其他答案的答案。
phonetagger

嗨,Phone Tagger,三年前我写原始帖子时,这将是一个很有帮助的评论,但是,正如您提到的,积分值已经改变。我不再记得我指的是哪篇文章,并且今天也不会用点值来指代它们。不管怎么说,还是要谢谢你。
Ben Personick

我环顾四周,我相信我指的是paxdiablo,所以我修改了文字以表明这一点。
Ben Personick

10

如果您要检测是否存在,这是最简单的解决方案:

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

这对于将Windows命令的输出放入布尔变量非常有用。只需将echo替换为要运行的命令即可。您也可以将Findstr的字符串串在一起,以使用管道进一步限定语句。用于服务控制的EG(SC.exe)

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

该程序将评估SC Query for Windows更新服务的输出,该输出以多行文本形式出现,找到包含“状态”的行,然后查找该行上是否出现单词“ 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

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

注意:您可以将两个变量用作参数。


1

更好的答案是在这里

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

在使用SET链接所解决的问题中,解决特定且独特的需求,因此提及“ SET”非常重要。但是,它似乎并未在当前的讨论中添加任何内容,因为已经提供了将命令传递给FIND命令并测试结果的方法
Ben Personick


0

文件中搜索子字符串的解决方案也可以搜索字符串,例如。findfindstr
在您的情况下,简单的解决方案是将字符串传递到命令中,而不是提供文件名。

区分大小写的字符串:
echo "abcdefg" | find "bcd"

忽略字符串的大小写:
echo "abcdefg" | find /I "bcd"

如果找不到匹配项,您将在CMD上得到一个空行响应,并且%ERRORLEVEL%设置为1

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.