SET Command
Moderator: DosItHelp
-
- Posts: 2
- Joined: 19 Dec 2011 18:28
SET Command
Hi, I am relatively new to batch scripting. I was looking into the batch script to FTP only new files found on this website.
For /F "Delims=" %%A In ('"Ftp -v -i -s:"%temp%\%~n0.ftp"|Findstr %FindStrArgs%"') Do (
Call Set "FileList=%%FileList%% "%%A""
)"
I came across the command above.
How should I be reading ('"Ftp -v -i -s:"%temp%\%~n0.ftp"|Findstr %FindStrArgs%"') and Call Set "FileList=%%FileList%% "%%A""?
Does it open child command window and run the ftp script which lists the files in the folder and then using Findstr to find all files ending in ".txt" and sends that as output to the for loop which iterate through the output of the two commands adding it to a Filelist. FindStrArgs is /E /C:".txt".
Does Call Set "FileList=%%FileList%% "%%A"" act as append to FileList, if so, how does that work?
Thanks
For /F "Delims=" %%A In ('"Ftp -v -i -s:"%temp%\%~n0.ftp"|Findstr %FindStrArgs%"') Do (
Call Set "FileList=%%FileList%% "%%A""
)"
I came across the command above.
How should I be reading ('"Ftp -v -i -s:"%temp%\%~n0.ftp"|Findstr %FindStrArgs%"') and Call Set "FileList=%%FileList%% "%%A""?
Does it open child command window and run the ftp script which lists the files in the folder and then using Findstr to find all files ending in ".txt" and sends that as output to the for loop which iterate through the output of the two commands adding it to a Filelist. FindStrArgs is /E /C:".txt".
Does Call Set "FileList=%%FileList%% "%%A"" act as append to FileList, if so, how does that work?
Thanks
-
- Expert
- Posts: 442
- Joined: 01 Aug 2010 17:13
- Location: Canadian Pacific
- Contact:
Re: SET Command
Yeah you got it right.
First loop example:
expands to
expands to
Second loop:
expands to
expands to
And so on...
I don't like the placement of quotation marks though, they are improper. Use this so the contents of %%A aren't exposed to the command interpreter:
First loop example:
Code: Select all
Call Set "FileList=%%FileList%% "%%A""
expands to
Code: Select all
Set "FileList=%FileList% "a_file.txt""
expands to
Code: Select all
Set "FileList= "a_file.txt""
Second loop:
Code: Select all
Call Set "FileList=%%FileList%% "%%A""
expands to
Code: Select all
Set "FileList=%FileList% "b_file.txt""
expands to
Code: Select all
Set "FileList= "a_file.txt" "b_file.txt""
And so on...
I don't like the placement of quotation marks though, they are improper. Use this so the contents of %%A aren't exposed to the command interpreter:
Code: Select all
Call Set FileList=%%FileList%% "%%A"
Re: SET Command
orange_batch showed how the SET works, but you might be confused as to why it was done that way.
Normal %var% expansion takes place at parse time, and everything within the for loop is parsed at once. So even though the value of FileList changes, the expansion of %FileList% remains constant. Using the CALL SET with double percents gets the expansion out of the FOR loop context, where it does get parsed again.
An alternate and more efficient way to get this to work is to use delayed expansion.
Instead of expansing %FileList% once at parse time, !FileList! is expanded at execution time, once for each iteration of the loop.
What orange_batch is referring to are special characters like & and ^ (both of which are legal in file names) have special significance to the batch parser. If you want the characters to be treated as literals then you must either quote them or escape them. For example "&" or ^&.
The following is generally good for building a list without quotes in the value. But for a list of filenames, orange_batch's suggestion is better
Dave Benham
Normal %var% expansion takes place at parse time, and everything within the for loop is parsed at once. So even though the value of FileList changes, the expansion of %FileList% remains constant. Using the CALL SET with double percents gets the expansion out of the FOR loop context, where it does get parsed again.
An alternate and more efficient way to get this to work is to use delayed expansion.
Code: Select all
setlocal enableDelayedExpansion
For /F "Delims=" %%A In ('"Ftp -v -i -s:"%temp%\%~n0.ftp"|Findstr %FindStrArgs%"') Do (
set "FileList=!FileList! %%A"
)"
(the remainder has been edited in response to orange-batch comments)orange_batch wrote:I don't like the placement of quotation marks though, they are improper. Use this so the contents of %%A aren't exposed to the command interpreter:Code: Select all
Call Set FileList=%%FileList%% "%%A"
What orange_batch is referring to are special characters like & and ^ (both of which are legal in file names) have special significance to the batch parser. If you want the characters to be treated as literals then you must either quote them or escape them. For example "&" or ^&.
The following is generally good for building a list without quotes in the value. But for a list of filenames, orange_batch's suggestion is better
Code: Select all
call set "FileList=%%FileList%% %%A"
Dave Benham
Last edited by dbenham on 20 Dec 2011 09:40, edited 1 time in total.
-
- Expert
- Posts: 442
- Joined: 01 Aug 2010 17:13
- Location: Canadian Pacific
- Contact:
Re: SET Command
But Dave, if all %%A are quoted, text within FileList is never exposed anyway.
These repeated explanations of delayed expansion are becoming tiring huh, we should just have a thread to link to.
These repeated explanations of delayed expansion are becoming tiring huh, we should just have a thread to link to.
Re: SET Command
Duh I momentarily lost my mind.orange_batch wrote:But Dave, if all %%A are quoted, text within FileList is never exposed anyway.
Generally I like unquoted values, but your way is definitely much better when building a list of files. The quotes might be needed to differentiate between space delimiters and space in a file name.
We desperately need some Wiki style pages, but I think that has been discussed already and did not get very far. Epic-ish Ideaorange_batch wrote:These repeated explanations of delayed expansion are becoming tiring huh, we should just have a thread to link to.
It's a shame, because collectively we have a tremendous body of knowledge that could be put to good use if we could only collect, format and index it in a sensible way.
-
- Posts: 2
- Joined: 19 Dec 2011 18:28
Re: SET Command
Thanks!
Just have one more question: why is it call set and not just set?
The same occurs in the section of code following
for /f "tokens=1,* delims=]" %%A in ('find /n /v "" "%src%"') do (
if /i "%%B"=="%emk%" set "bExtr="&set "bSubs="
if defined bExtr if defined bSubs (call echo.%%B) ELSE (echo.%%B)
if /i "%%B"=="%bmk%" set "bExtr=Y"
if /i "%%B"=="%bmk%:S" set "bExtr=Y"&set "bSubs=Y"
)
EXIT /b
there is call echo and echo. In the above code I don't understand the point of having two flags unless call echo and echo performs two different functions.
The above code in ftp only new files functions to extract a section of ftp text in a batch script so that it can be run separately as .ftp.
Just have one more question: why is it call set and not just set?
The same occurs in the section of code following
for /f "tokens=1,* delims=]" %%A in ('find /n /v "" "%src%"') do (
if /i "%%B"=="%emk%" set "bExtr="&set "bSubs="
if defined bExtr if defined bSubs (call echo.%%B) ELSE (echo.%%B)
if /i "%%B"=="%bmk%" set "bExtr=Y"
if /i "%%B"=="%bmk%:S" set "bExtr=Y"&set "bSubs=Y"
)
EXIT /b
there is call echo and echo. In the above code I don't understand the point of having two flags unless call echo and echo performs two different functions.
The above code in ftp only new files functions to extract a section of ftp text in a batch script so that it can be run separately as .ftp.
Re: SET Command
Re-read my first post, and then read orange-batch's. We already tried to explain why it is written the way it is, and how it works.