Toplu iş dosyası: Alt dizenin dize olup olmadığını bulma (dosyada değil)


208

Bir toplu iş dosyasında, bir dize var abcdefg. Dizede olup olmadığını kontrol etmek istiyorum bcd.

Ne yazık ki tüm çözümler görünüyor bir alt dize için bir dize değil, bir alt dize için bir dosya arama .

Bunun için kolay bir çözüm var mı?


5
BTW, ya genelde var Windowsve cmd ya bu kadar ms-dos. MSDOS uzun süredir Windows'un parçası değil .
paxdiablo

Yanıtlar:


288

Evet, ikameleri kullanabilir ve orijinal dizeyi kontrol edebilirsiniz:

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

%str1:bcd=%Bit yerini alacak bcdiçinde str1orijinalinden farklı hale boş bir dize ile.

Orijinalde bir bcddize yoksa , değiştirilen sürüm aynı olacaktır.

Aşağıdaki komut dosyasıyla test edildiğinde, kod iş başında gösterilir:

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

Ve çeşitli koşuların sonuçları:

c:\testarea> testprog hello

c:\testarea> testprog abcdef
It contains bcd

c:\testarea> testprog bcd
It contains bcd

Birkaç not:

  • ifİfadesi bu çözümün et, her şey destek şeyler.
  • xEşitlik iki tarafın önce dize sağlamaktır bcdtamam çalışır. Ayrıca belirli "uygunsuz" başlangıç ​​karakterlerine karşı da koruma sağlar.

7
Bir FOR döngüsünde dize değiştirme işleminin nasıl yapıldığını düşünüyorsanız: stackoverflow.com/a/6310580/623622
Czarek Tomczak

60
Bu harika ama arama değeri sabit (bcd gibi) değil, bunun yerine bir değişken olduğunda bu işe almak için mücadele etti. Uzun zaman sonra nihayet anladım. SearchVal bildirildiğini varsayarsak, "x! Str1:% searchVal% =!" == "x% str1%"
Gary Brunton

7
@Gary, bu sorunun şartlarından biri olmadığı için muhtemelen farklı bir soru sormuş olmalısınız, belki de bu soruya referans olarak geri dönmelisiniz. Yardım etmeye istekli olan insanların sıkıntısı yok. Aslında, hala bu soruyu sormanız ve kendiniz cevaplamanız gerekir (şimdi anladınız), böylece gelecekteki araştırmacılar için yararlı olacaktır. Kendi kendine cevaplama kabul edilebilir.
paxdiablo

6
Çok iyi bir çözüm, ancak çift tırnak içine almanız gerekir veya değerlerinde boşluk olan değişkenlerle çalışmaz, örneğin: eğer değilse "x% str1: bcd =%" == "x% str1%" echo bcd içerir
Helge Klein

4
"'= str1 şu anda beklenmedikti"
Berit Larsen

104

Kaynak dizgiyi birbirine bağlayabilir ve desen dizesinin bulunup bulunmadığını görmek findstriçin değerini kontrol edebilirsiniz ERRORLEVEL. Sıfır değeri başarıyı gösterir ve desen bulundu. İşte bir örnek:

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

Bu CMD.EXE çalıştırıldığında:

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 sonra argüman eksik. Bir desen bulunamadı"
Berit Larsen

47

Genellikle böyle bir şey yaparım:

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

Misal:

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

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

Çıktı:

TRUE
FALSE

Bunun en iyi yol olup olmadığını bilmiyorum.


Dosya adlarını tekrar tekrar bulmam ve karşılaştırmam gerekiyordu. Benim için de işe yarayan tek çözüm buydu! Süper kullanışlı ve çok basit.
SirJames

24

Uyumluluk ve kullanım kolaylığı için bunu yapmak için genellikle FIND kullanmak daha iyidir.

Ayrıca, büyük / küçük harfe duyarlı veya büyük / küçük harfe uymak isteyip istemediğinizi de göz önünde bulundurmalısınız.

78 puanlı yöntem (paxdiablo'nun gönderisine atıfta bulunduğuma inanıyorum) sadece Case Sensitively ile eşleşecek, bu yüzden eşleştirmek isteyebileceğiniz her yineleme için her vaka varyasyonu için ayrı bir kontrol yapmalısınız.

(Ne acı! Kontrolün gerçekleşmesi için 9 farklı test anlamına gelen sadece 3 harfle!)

Ek olarak, komut çıkışını, bir döngüdeki bir değişkeni veya toplu iş / CMD'nizde düz ileri olmayan bir işaretçi değişkeninin değerini eşleştirmek tercih edilir.

Bu nedenlerden dolayı, bu tercih edilen bir alternatif yöntemdir:

Kullan: [/ I] [/ V] "Eşleşecek Karakterleri" Bul

[/ I] (büyük / küçük harf duyarsız) [/ V] (Karakter içermemelidir)

Tek Hat Olarak:

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

Çok çizgili:

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

Belirtildiği gibi, bu, dize ikamesine izin veren değişkenlerde olmayan şeyler için harikadır:

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.

küçük harf duyarlılığı sorunu için kullanabileceğiniz setlocal EnableExtensionssonra IF /Iharf duyarsız karşılaştırmalar yapmak.
cychoi

1
Bu gerçekten bir seçenek değil, çünkü yine de karakterleri "EĞER" Karşılaştırma için ayırmanız gerekir. EĞER "Beğenmek" terimleri eşleşmez OP ve cevap için özel çözümler arıyor.,
Ben Personick

Merhaba Ben, Lütfen diğer cevaplara sahip oldukları puan sayısına göre atıfta bulunmayın. Bu muhtemelen değişecek. Lütfen cevabınızı yazarın adı ya da bu cevapta kullanılan tekniği tanımlayan kısa bir cümle ile diğer cevaba bakarak güncelleyin.
phonetagger

Merhaba Telefon Tagger, bu üç yıl önce orijinal yazıyı yazarken yararlı bir yorum olurdu, ancak puan değerlerinden bahsettiğiniz gibi hepsi değişti. Artık hangi gönderiye atıfta bulunduğumu hatırlamıyorum ve bugün onlara puan değerleri ile atıfta bulunmam. Yine de teşekkürler.
Ben Personick

Etrafıma baktım ve paxdiablo'dan bahsettiğime inanıyorum, bu yüzden bunu göstermek için metni değiştirdim.
Ben Personick

10

Varlığını tespit ediyorsanız, en kolay çözüm şudur:

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

Bu, Windows komutlarının çıktısını bir boole değişkenine bırakmak için harika çalışır. Yankıyı, çalıştırmak istediğiniz komutla değiştirmeniz yeterlidir. Pipo kullanarak bir ifadeyi daha da nitelemek için Findstr'ları birlikte dizebilirsiniz. Servis Kontrolü için EG (SC.exe)

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

Bu, çok satırlı bir metin olarak ortaya çıkan Windows güncelleştirme hizmetleri için SC Sorgusu'nun çıktısını değerlendirir, "durum" içeren satırı bulur, ardından bu satırda "çalışıyor" sözcüğünün oluşup oluşmadığını bulur ve hata düzeyini buna göre ayarlar.


6
IF İfadenizi Geri Vardınız .. Orijinaline abcdefg ile bakmak ve mantığınızı ters çevirmek. İşe yarıyor. Sahip olduğunuz şekilde değil. 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 tersine çevrilmiş mantıkla doğru olsa bile + 1'in zamanı geldi. Bu basit ve kullanımı kolay bir çözümdür.
Laryx Decidua

2

Muhtemelen bu cevap ile biraz geç geliyorum, ancak kabul edilen cevap sadece bir "sabit kodlu dize" arama dizesinin bir parçası olup olmadığını kontrol etmek için çalışır.

Dinamik arama için bunu yapmanız gerekir:

SET searchString=abcd1234
SET key=cd123

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

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

Not: İki değişkeni bağımsız değişken olarak alabilirsiniz.


1

Daha iyi cevap buradaydı :

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

SET kullanarak bağladığınız soruda belirli ve benzersiz bir ihtiyaç çözülüyor, bu yüzden "SET" den bahsetmek önemlidir. Ancak, FIND komutuna bir komut verme ve sonucu test etme yöntemi zaten sağlandığından, geçerli tartışmaya hiçbir şey
eklemiyor gibi görünüyor


0

Bir dosyada bir alt dizeyi arayan çözümler , örneğin bir dizeyi de arayabilir . findveya findstr.
Sizin durumunuzda, kolay çözüm bir dosya adı sağlamak yerine komuta bir dize eklemek olacaktır.

büyük / küçük harfe duyarlı dize:
echo "abcdefg" | find "bcd"

dize durumunu yoksay:
echo "abcdefg" | find /I "bcd"

Eşleşme bulunmazsa, CMD'de boş bir satır yanıtı alırsınız ve% ERRORLEVEL%% 1 olarak ayarlanmış

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.