Batch file: Tìm nếu chuỗi con nằm trong chuỗi (không phải trong tệp)


208

Trong một tập tin bó, tôi có một chuỗi abcdefg. Tôi muốn kiểm tra xembcd trong chuỗi.

Thật không may, có vẻ như tất cả các giải pháp tôi đang tìm kiếm tệp cho một chuỗi con, không phải là một chuỗi cho một chuỗi con.

Có một giải pháp dễ dàng cho việc này?


5
BTW, nó thường là một trong hai Windowscmd hay đó ms-dos. MSDOS đã không còn là một phần của Windows trong một thời gian dài .
paxdiablo

Câu trả lời:


288

Có, bạn có thể sử dụng thay thế và kiểm tra đối với chuỗi ban đầu:

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

Các %str1:bcd=%bit sẽ thay thế một bcdtrong str1với một chuỗi rỗng, làm cho nó khác biệt so với bản gốc.

Nếu bản gốc không chứa một bcdchuỗi trong đó, phiên bản sửa đổi sẽ giống hệt nhau.

Thử nghiệm với đoạn script sau sẽ hiển thị nó trong hành động:

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

Và kết quả của các lần chạy khác nhau:

c:\testarea> testprog hello

c:\testarea> testprog abcdef
It contains bcd

c:\testarea> testprog bcd
It contains bcd

Một vài lưu ý:

  • Các if tuyên bố là thịt của giải pháp này, mọi thứ khác là hỗ trợ các công cụ.
  • Các xtrước khi hai bên của bình đẳng là để đảm bảo rằng các chuỗi bcdcông trình okay. Nó cũng bảo vệ chống lại một số nhân vật bắt đầu "không đúng".

7
Nếu bạn đang tìm cách thay thế chuỗi trong vòng lặp FOR: stackoverflow.com/a/6310580/623622
Czarek Tomczak

60
Điều này thật tuyệt nhưng tôi đã đấu tranh để làm cho nó hoạt động khi giá trị tìm kiếm không phải là hằng số (như bcd) mà thay vào đó là một biến. Sau nhiều thời gian cuối cùng tôi cũng đã hiểu ra. Giả sử searchVal đã được khai báo, "x! Str1:% searchVal% =!" == "x% str1%"
Gary Brunton

7
@Gary, vì đó không phải là một trong những yêu cầu của câu hỏi này, có lẽ bạn nên hỏi một câu hỏi khác, có lẽ liên kết lại với câu hỏi này như một tài liệu tham khảo. Không thiếu người sẵn sàng giúp đỡ. Trên thực tế, bạn vẫn tự hỏi câu hỏi đó và tự trả lời (bây giờ bạn đã tìm ra nó) để nó hữu ích cho những người tìm kiếm trong tương lai. Tự trả lời được coi là chấp nhận được.
paxdiablo

6
Giải pháp rất tốt, nhưng bạn cần đặt trong dấu ngoặc kép hoặc nó sẽ không hoạt động với các biến có khoảng trắng trong giá trị của chúng, ví dụ: if not "x% str1: bcd =%" == "x% str1%" echo chứa bcd
Helge Klein

4
"'= str1 thật bất ngờ vào thời điểm này"
Berit Larsen

104

Bạn có thể đặt chuỗi nguồn vào findstrvà kiểm tra giá trị của ERRORLEVELđể xem chuỗi mẫu có được tìm thấy không. Giá trị bằng 0 biểu thị thành công và mô hình đã được tìm thấy. Đây là một ví dụ:

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

Khi điều này được chạy trong CMD.EXE, chúng tôi nhận được:

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

"TÌM KIẾM: Đối số bị thiếu sau / C. Có một mẫu không tìm thấy"
Berit Larsen

47

Tôi thường làm một cái gì đó như thế này:

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

Thí dụ:

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

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

Đầu ra:

TRUE
FALSE

Tôi không biết nếu đây là cách tốt nhất.


Tôi cần phải đệ quy tìm và so sánh tên tập tin. Đây là giải pháp duy nhất hiệu quả với tôi! Siêu tiện dụng và rất đơn giản.
SirJames

24

Để tương thích và dễ sử dụng, tốt hơn hết là sử dụng TÌM để làm điều này.

Bạn cũng phải xem xét nếu bạn muốn khớp trường hợp nhạy cảm hoặc trường hợp không nhạy cảm.

Phương pháp với 78 điểm (tôi tin rằng tôi đã đề cập đến bài đăng của paxdiablo) sẽ chỉ khớp với Case Sensitively, do đó bạn phải đặt một kiểm tra riêng cho mọi biến thể trường hợp cho mỗi lần lặp có thể bạn muốn khớp.

(Thật là đau! Chỉ có 3 chữ cái có nghĩa là 9 bài kiểm tra khác nhau để hoàn thành kiểm tra!)

Ngoài ra, nhiều lần nên kết hợp đầu ra lệnh, biến trong vòng lặp hoặc giá trị của biến con trỏ trong lô / CMD của bạn không đơn giản như trước.

Vì những lý do này, đây là một phương pháp thay thế thích hợp hơn:

Sử dụng: Tìm [/ I] [/ V] "Nhân vật phù hợp"

[/ I] (Không phân biệt chữ hoa chữ thường) [/ V] (KHÔNG được chứa các ký tự)

Như một dòng:

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

Đa dòng:

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

Như đã đề cập, điều này rất tốt cho những thứ không có trong biến cũng cho phép thay thế chuỗi:

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.

đối với vấn đề độ nhạy trường hợp, bạn có thể sử dụng setlocal EnableExtensionssau đó IF /Iđể so sánh trường hợp không nhạy cảm.
cychoi

1
Đó thực sự không phải là một lựa chọn vì bạn vẫn cần cách ly các ký tự để so sánh "NẾU". NẾU không khớp trong Điều khoản "Thích" như OP và các giải pháp cụ thể mà tôi đã trả lời đang tìm kiếm.,
Ben Personick

Xin chào Ben, Vui lòng không tham khảo các câu trả lời khác theo số điểm họ có. Điều đó có khả năng thay đổi. Vui lòng cập nhật câu trả lời của bạn đề cập đến câu trả lời khác bằng tên tác giả của câu trả lời đó hoặc bằng một cụm từ ngắn gọn mô tả kỹ thuật được sử dụng trong câu trả lời đó.
phonetagger

Xin chào Điện thoại Tagger, đó sẽ là một nhận xét hữu ích ba năm trước khi tôi viết bài gốc, tuy nhiên khi bạn đề cập đến các giá trị điểm đã thay đổi. Tôi không còn nhớ bài đăng nào mà tôi đã đề cập và tôi sẽ không đề cập đến chúng theo giá trị điểm ngày hôm nay. Dẫu sao cũng xin cảm ơn.
Ben Personick

Tôi nhìn xung quanh và tôi tin rằng tôi đang đề cập đến paxdiablo, vì vậy tôi đã sửa đổi văn bản để cho thấy điều đó.
Ben Personick

10

Nếu bạn đang phát hiện sự hiện diện, đây là giải pháp đơn giản nhất:

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

Điều này hoạt động rất tốt để thả đầu ra của các lệnh windows vào một biến boolean. Chỉ cần thay thế echo bằng lệnh bạn muốn chạy. Bạn cũng có thể xâu chuỗi Findstr lại với nhau để tiếp tục đủ điều kiện tuyên bố bằng cách sử dụng các đường ống. Kiểm soát dịch vụ (SC.exe)

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

Người ta đánh giá đầu ra của SC Query cho các dịch vụ cập nhật windows xuất hiện dưới dạng văn bản nhiều dòng, tìm dòng chứa "trạng thái" sau đó tìm nếu từ "chạy" xảy ra trên dòng đó và đặt lỗi theo đó.


6
Bạn có Tuyên bố IF của bạn lạc hậu .. Nhìn vào bản gốc với abcdefg và bạn lật lại logic của mình. Nó hoạt động. Cách bạn có nó, nó không. SET STRING=abcdefgh SET SUBSTRING=bcd ECHO %STRING% | FINDSTR /C:"%SUBSTRING%" >nul & IF ERRORLEVEL 1 (ECHO CASE FALSE) else (ECHO CASE TRUE)
Leptonator

2
+1 là do mặc dù @Leptonator đúng với logic đảo ngược. Đây là một giải pháp đơn giản và dễ sử dụng.
Laryx Decidua

2

Có lẽ tôi đến hơi muộn với câu trả lời này, nhưng câu trả lời được chấp nhận chỉ hoạt động để kiểm tra xem "chuỗi mã hóa cứng" có phải là một phần của chuỗi tìm kiếm hay không.

Đối với tìm kiếm động, bạn sẽ phải làm điều này:

SET searchString=abcd1234
SET key=cd123

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

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

Lưu ý: Bạn có thể lấy hai biến làm đối số.


1

Câu trả lời tốt hơn đã có ở đây :

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

Trong câu hỏi bạn liên kết bằng cách sử dụng SET là giải quyết một nhu cầu cụ thể và duy nhất, do đó, điều quan trọng là phải đề cập đến "SET". Tuy nhiên, dường như không thêm bất cứ điều gì vào cuộc thảo luận hiện tại, vì phương pháp chuyển một lệnh đến lệnh FIND và kiểm tra kết quả đã được cung cấp
Ben Personick


0

Các giải pháp tìm kiếm tệp cho một chuỗi con cũng có thể tìm kiếm một chuỗi , ví dụ. findhoặc findstr.
Trong trường hợp của bạn, giải pháp dễ dàng sẽ là nối một chuỗi vào lệnh thay vì cung cấp tên tệp, vd.

chuỗi phân biệt chữ hoa chữ thường:
echo "abcdefg" | find "bcd"

bỏ qua trường hợp của chuỗi:
echo "abcdefg" | find /I "bcd"

NẾU không tìm thấy kết quả khớp, bạn sẽ nhận được phản hồi dòng trống trên CMD và% ERRORLEVEL% được đặt thành 1

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.