How to perform wildcard string comparison in batch file

09
2014-02
  • MyDaftQuestions

    My batch file writes a list of files on screen where it contains the .cs extension

    for /F "usebackq delims=" %%A in (`cleartool ls  -rec ^| find /V "Rule:" ^| find /V "hijacked" ^| find /V "eclipsed" ^| find /V "-->"`) do ( 
        if "%%~xA"==".cs"  echo %%A
    )
    

    This works fine. I want to enhance the functionality by adding another condition. I want to remove a certain word if it exists in the phrase. The word is obj

    Examples of my results are

    myThing\obj\this.cs
    obj\other\that\this.cs
    debug\this\that.cs

    I tried

    for /F "usebackq delims=" %%A in (`cleartool ls  -rec ^| find /V "Rule:" ^| find /V "hijacked" ^| find /V "eclipsed" ^| find /V "-->"`) do ( 
    if "%%~xA"==".cs" if NOT "%%A"=="*obj*" echo %%A
    )
    

    but this doesn't change the results compared to the first.

    I think my if syntax is correct, and the issue is actually with the "%%A"=="*obj*"

  • Answers
  • Michał Sacharewicz

    You were thinking correctly: the wildcards (*) are not supported.

    A good workaround for the problem is findstr, though you need to retrieve result via %ERRORLEVEL% and I think you must cache it through another variable (so that next if does not override it's value):

    echo %%A | findstr /C:"obj"
    set obj_errorlevel=%errorlevel%
    
    if "%%~xA"==".cs" if "%obj_errorlevel%"=="1" echo %%A
    

    ...but that is a hard way.

    An even easier way is to add the condition to the source command (the one inside if) by adding another pipe stage: ^| find /V "obj":

    for /F "usebackq delims=" %%A in (`cleartool ls  -rec ^| find /V "Rule:" ^| find /V "hijacked" ^| find /V "eclipsed" ^| find /V "-->" ^| find /V "obj"`)
    
  • Tonny

    I dont think you can use 2 if's like that. Try:

    for    xxxxxxx   (
       if first-condition (
           if second-condition (
             statement(s)
           )
       )
    )
    
  • techie007

    I believe your edit is correct, in that you can't use wildcards in the If string compare. It's actually looking for *obj*, including the asterisks.

    Perhaps use FindStr instead, by piping any .cs matches through it. It returns an errorlevel of 0 if found, and 1 if not found.

    Code example:

    for /F "usebackq delims=" %%A in (`cleartool ls  -rec ^| find /V "Rule:" ^| find /V "hijacked" ^| find /V "eclipsed" ^| find /V "-->"`) do ( 
      if "%%~xA"==".cs" echo %%A | findstr /C:"obj" 1>nul & if errorlevel 1 echo %%A
    )
    
  • Marcks Thomas

    The asterisks are not interpreted as wildcards, so the condition evaluates to false. Instead of a second if-statement, you can use findstr to determine whether the variable contains the text 'obj'. The command sets %errorlevel% to zero if a match has been found, to zero otherwise.

    A convenient way of using this value is through the conditional command seperators && and ||. A command appended with || will only be executed if the previous command returned a non-zero error level, e.g.:

    (echo %%A | findstr /R .*obj.*)>NUL || 
      if "%%~xA"==".cs" echo %%A
    

    The addition of >NUL is important in this scenario. Without suppressing the output, both the first line and the second line could print the variable %%A. To avoid confusion, you'll want different cases to produce different results.

    Of course, if you're already using findstr, you could get rid of the if-statement and its body altogether. The readability isn't great either way; the code below is provided as an alternative.

    (echo %%A|findstr /R /V ".*obj.*")|findstr /R /C:"\.cs $"
    
  • JSanchez

    A solution that might work for what you want to do. This uses SET's string substitution, as explained at Rob van der Woude's site.

    @echo off
    set _myvar=this\has\obj\in the string
    echo Original: %_myvar%
    ::replace the string obj in _myvar
    set _myvar=%_myvar:obj=%
    ::replace any double back-slashes in _myvar
    set _myvar=%_myvar:\\=\%
    echo Withou obj: %_myvar%
    

    _myvar originally contains the string 'obj' in it. The first time we remove the string using SET's string substitution. The second time, we remove any double-slashes that might be left over due to the location of 'obj'. After the colon, you have the string you want to look for in the variable. The string to replace with comes after the equal sign before the end of the substitution.

    Hope that helps!


  • Related Question

    How to center batch files when they open up?
  • Kevin

    How do I center batch files when they open up? I mean not by dragging but every time they open up they are automatically centered like is there a command? I am trying to make a game like that. And these are the game files I want to be centered. They're separate:

    @echo off
    type c1.txt
    gotoxy 0 1
    ping localhost -n 2 > Nul
    start c2.bat
    exit
    

  • Related Answers
  • Moses

    The easy way is simply modify the screen width of the Dos Box.

    To set it up in a batch file:

    mode con: cols=170 lines=50


    FYI, I don't know how to "lock that. It will change the resolution during the Batch File run, however next time you open a command prompt, it reverts to the old settings. At least the batch File runs as you wish.

    To determine best size for what your doing:

    • open cmd
    • Right click upper rail of CMD Window, choose Properties
    • Click "Layout" -Middle Choice=Window Size
    • Change that to
    • Width: 150
    • Height: 70

      • "Window Position: Check "Let System Position Window"

    For your resolution, might be different (no clue how to make it user specific)


    170x50 = Absolutely perfect window size for me. I can still see top url and bottom tabs, but takes up almost entire screen.

    As an F.Y.I.

    As I type this it's 2013, thus "Popular" is the Wide LCD/Short/Squat Height.

    My Resolution is set at 1400x1050 It's rated "20-Inch" It's 21"-across/12"-tall (see, wide/squat)
    (might make a difference, consider tweaking it)

  • Matthieu Cartier

    You can do this with IE popups using VBS, but as far as I am aware that cannot be done to manipulate an existing command prompt. You may want to try using an AutoHotkey script within the batch file to do something like (A_ScreenWidth/2)-(Width/2), or use CenterWindow() in VC.

  • Linker3000

    In the days of DOS, you used to be able to manipulate the screen output by loading up the ANSI.SYS driver and using ESCape sequences or by creating your text/images using an app like thedraw.

    Checking for a modern solution for ANSI.SYS I came across ANSICON. With this app/utility installed, putting ANSI escape sequences in your txt file may work - I can't try it at the moment as I only have a Linux laptop at my disposal so feedback would be useful!

    Edit: Thinking about things, I don't believe this will make centring text any easier as I cannot find an ANSI sequence that defines 'centre text' on a display - only for a printer - but this may be of use for designing screens so I will leave the answer here as it is.