Reputation: 3970
I have the following command in a CMD.EXE batch file executing in a Windows 7 environment:
FOR %%f IN ("C:\TEMP\FILE.TXT" "C:\TEMP\FILE2.TXT") DO (
ECHO %%f
)
This produces the following output:
"C:\TEMP\FILE.TXT"
"C:\TEMP\FILE2.TXT"
However, I have found that if I change the FOR
command to include the presence of a wild card such as ? or * in the file names, I get the results I would expect, which is only the echo of C:\TEMP\FILE2.TXT
IE:
FOR %%f IN ("C:\TEMP\FILE.TXT?" "C:\TEMP\FILE2.TXT?") DO (
ECHO %%f
)
Produces:
C:\TEMP\file2.txt
The documentation for the FOR
command states that:
FOR %variable IN (set) DO command [command-parameters] %variable Specifies a single letter replaceable parameter. (set) Specifies a set of one or more files. Wildcards may be used. command Specifies the command to carry out for each file. command-parameters
It seems that if no wild card is present in the (set)
specifier, the FOR
command treats the file paths as string literals and just iterates over them. Am I misunderstanding the documentation? It seems to me that the presence (or lack of) a wild card in the file (set)
specifier should not impact behavior.
Upvotes: 2
Views: 140
Reputation: 70923
You are understanding it perfectly.
The for
command is designed to iterate over a set of elements that don't need to be files or folders (to be more precise, they are not required to exist in the file system).
But when one of the elements in the set include a wildcard it will be seen as a query to the filesystem that needs to be resolved and the element in the set will be replaced with the list of files/folders that match the wildcard expression.
You should note that this query is not always static. During the query only the first matching file/folder is retrieved, but if the file system informs that there are more files/folders matching the wildcard expression, sucesive queries will be done to retrieve the remaining elements. If any file is added/renamed and matches the wildcard expression it can or not (depending on the file system, naming, ...) be included in the list.
An no, there is no way to escape the wildcard expression. The presence of *
or ?
in an element in the set will execute the file system query when this element of the set is reached.
While executing the code in the do
clause, if a for
replaceable parameter modifier (the %%~...
) is used to retrieve information of the current referenced element, the file system will also be accessed.
If the file/folder exists (the element in the set is a valid reference or it has been retrieved by expanding a wildcard expression), the requested information is retrieved, but if the file/folder does not exist, depending on the specific modifier you can get :
what SHOULD BE the correct/logical value IF the file/folder exist: drive, path, name, extension, just the parts that you included in the element or, if missing, the information retrieved from the file system assuming the element is a file/folder reference relative to the current active directory.
An particular case of this point is the short name (~s
modifier). It will return the short version for those directories in the path to the file/folder reference that exist and has a short name stored on the file system, and the indicated string literal for those that does not have a short name or that does not exist.
an empty string: attributes, size, timestamp, all the elements that require an existing file/folder to retrieve its information.
Upvotes: 5