How to perform wildcard string comparison in batch file
2014-02
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*"
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"`)
I dont think you can use 2 if's like that. Try:
for xxxxxxx (
if first-condition (
if second-condition (
statement(s)
)
)
)
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
)
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 $"
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!
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
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)
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.
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.