I'm trying to accomplish the following ridiculous task:
I have a text file containing a set of fully qualified filesnames. I want to iterate through the file and append each line to a common variable, that can be passed to a command line tool. For example, the file might be:
C:\dir\test.txt
C:\WINDOWS\test2.txt
C:\text3.txt
and I'd like to assign them to some variable 'a' such that:
a = "C:\dir\test.txt C:\WINDOWS\test2.txt C:\text2.txt"
A secondary question is - what is a good batch file reference? I'm finding some stuff in the Windows material, and a lot of home-grown websites, but nothing particularly complete.
As for references, SS64.com isn't bad. Rob van der Woude gets linked fairly often, too.
As for your problem, that's easy:
@echo off
setlocal enableextensions enabledelayedexpansion
set LIST=
for /f %%x in (yourfile.txt) do (
set LIST=!LIST! "%%x"
)
echo %LIST%
endlocal
More in-depth explanation:
setlocal enableextensions enabledelayedexpansion
We're enabling delayed expansion here. This is crucial as otherwise we wouldn't be able to manipulate the list of files within the for
loop that follows.
for /f %%x in (yourfile.txt) do (
set LIST=!LIST! "%%x"
)
for /f
iterates over lines in a file, so exactly what we need here. In each loop iteration we append the next line to the LIST
variable. Note the use of !LIST!
instead of the usual %LIST%
. This signals delayed expansion and ensures that the variable gets re-evaluated every time this command is run.
Usually cmd
expands variables to their values as soon as a line is read and parsed. For cmd
a single line is either a line or everything that counts as a line, which happens to hold true for blocks delimited by parentheses like the one we used here. So for cmd
the complete block is a single statement which gets read and parsed once, regardless of how often the interior of the loop runs.
If we would have used %LIST%
here instead of !LIST!
then the variable would have been replaced immediately by its value (empty at that point) and the loop would have looked like this:
for /f %%x in (yourfile.txt) do (
set LIST= "%%x"
)
Clearly this isn't what we wanted. Delayed expansion makes sure that a variable is expanded only when its value is really needed. In this case when the interior of the loop runs and constructs a list of file names.
Afterwards the variable %LIST%
or !LIST!
(now it doesn't really matter anymore which to use) contains the list of lines from the file.
Funnily enough, the help for the set
command includes exactly this example for delayed expansion:
Finally, support for delayed
environment variable expansion has
been added. This support is always
disabled by default, but may be
enabled/disabled via the /V command
line switch to CMD.EXE. See CMD /?
Delayed environment variable expansion
is useful for getting around the
limitations of the current expansion
which happens when a line of text is
read, not when it is executed. The
following example demonstrates the
problem with immediate variable
expansion:
set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "%VAR%" == "after" @echo If you see this, it worked
)
would never display the message, since
the %VAR% in BOTH IF statements is
substituted when the first IF
statement is read, since it logically
includes the body of the IF, which is
a compound statement. So the IF
inside the compound statement is
really comparing "before" with "after"
which will never be equal. Similarly,
the following example will not work as
expected:
set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%
in that it will NOT build up a list of
files in the current directory, but
instead will just set the LIST
variable to the last file found.
Again, this is because the %LIST% is
expanded just once when the FOR
statement is read, and at that time
the LIST variable is empty. So the
actual FOR loop we are executing is:
for %i in (*) do set LIST= %i
which just keeps setting LIST to the
last file found.
Delayed environment variable expansion
allows you to use a different
character (the exclamation mark) to
expand environment variables at
execution time. If delayed variable
expansion is enabled, the above
examples could be written as follows
to work as intended:
set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "!VAR!" == "after" @echo If you see this, it worked
)
set LIST=
for %i in (*) do set LIST=!LIST! %i
echo %LIST%
What you're after can be done with a FOR /F command.
Here's a good resource I've used many times:
http://www.robvanderwoude.com/batchfiles.php
A good book: Windows NT Shell Scripting by Tim Hill. The edition I have was published in 1998 but it is still valid for Windows command programs in Windows 2008.
type *commonfilepart* >> concat_result_file
OS: WINDOWS SERVER 2003