Words with star character are ignored in FOR loop

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

Words with star character are ignored in FOR loop

Post by MigrationUser »

11 Jul 2011 20:20
budhax


Hello,
This FOR loop ignores (jump over) strings including star character: *

Code: Select all

    SET d=aaa* file*.* file3.txt
    FOR %%f in (%d%) DO (ECHO.%%~f)
    FOR %%f in ("%d: =" "%") DO (ECHO.%%~f)
The output I got with this script is only the 3rd string: file3.txt
I would like to get this:

aaa*
file*.*
file3.txt

How tho solve my problem?
Thanks and regards.
CONFIG:
MS Windows 7 SP1, Firefox 5. Microsoft Windows [Version 6.1.7601]

Last edited by budhax (11 Jul 2011 20:25)

----------------------------

#2 12 Jul 2011 01:39
RG


You need to iterate through your list. Below is one way to do it:

Code: Select all

@echo off
SET d=aaa*.* file*.* file3.txt
CALL :Subr1 "%d%"
PAUSE
GOTO :eof

:Subr1
FOR /F "tokens=1*" %%f in ('ECHO.%~1') DO (
   ECHO.%%f
   CALL :Subr1  "%%g"
)
GOTO :eof
What :Subr1 is doing is starting with the entire string and removing one token at a time and passing the remainder of the line to a recursive call of itself until the entire original argument is consumed.

Last edited by RG (12 Jul 2011 01:59)

Windows Shell Scripting and InstallShield

----------------------------

#3 13 Jul 2011 08:09
flabdablet


The list you give to FOR between its parentheses is treated as a list of filenames, not general purpose strings. Any filenames containing wildcard characters (* or ?) get replaced with a list of the files in the current directory that match the resulting pattern. So if you do

Code: Select all

for %%F in (roo mon nap) do type nul >%%Fster.txt
for %%F in (*ster.txt) do echo %%F
you will see the second FOR command execute ECHO for each of the three files created by the first one.

If there are no files that match a wildcard pattern, FOR simply ignores that pattern. So I guess your current directory doesn't contain any files whose names start with "aaa" or "file".

If you need to iterate over a set of strings that could contain wildcard patterns without treating those specially, FOR is not the right tool. Something like this might work for you:

Code: Select all

call :each "echo {} nicely" aaa* file*.* file3.txt a b c d e f g h i "j k l m n o p" "enk
goto :eof

:: Run the command line passed as the first argument repeatedly, substituting
:: each of the remaining arguments in turn for the {} placeholder included in
:: the command line.

:each
@setLocal enableDelayedExpansion
@set template=%~1
@goto :eachArg
:eachCmd
@set command=%template:{}=!arg!%
%command%
:eachArg
@shift
@set arg=%1
@if defined arg goto eachCmd
@endLocal
@goto :eof
My gut feeling is that this will be rather less susceptible to weird quoting bugs than RG's recursive solution, though it will still surely have some - cmd has very wonky parsing rules, and strings containing ! and/or % will always be problematic.

Last edited by flabdablet (13 Jul 2011 09:26)

----------------------------

#4 16 Jul 2011 17:02
budhax


Thanks guys each of your solutions works fine in my script.

----------------------------

#5 16 Jul 2011 18:55
allal
budhax wrote:

CONFIG:
MS Windows 7 SP1, Firefox 5. Microsoft Windows [Version 6.1.7601]
strange ???!!!
i still can not figure out what firefox have to do with cmd in dealing with wildcard in a for loop

----------------------------

#6 20 Jul 2011 12:34
jumper


variant

Code: Select all

@echo off
setlocal enableextensions enabledelayedexpansion

set d=aaa* file*.* file3.txt

(set \=^

)&echo(%d: =!\!%

pause
or

Code: Select all

@echo off
setlocal enableextensions

set d=aaa* file*.* file3.txt

set "d=echo(%d: =&echo.%"
%d%

pause
Last edited by jumper (20 Jul 2011 12:36)
Post Reply