215

This batch file releases a build from TEST to LIVE. I want to add a check constraint in this file that ensures there is an accomanying release document in a specific folder.

"C:\Program Files\Windows Resource Kits\Tools\robocopy.exe" "\\testserver\testapp$"        
"\\liveserver\liveapp$" *.* /E /XA:H /PURGE /XO /XD ".svn" /NDL /NC /NS /NP
del "\\liveserver\liveapp$\web.config"
ren "\\liveserver\liveapp$\web.live.config" web.config

So I have a couple of questions about how to achieve this...

  1. There is a version.txt file in the \\testserver\testapp$ folder, and the only contents of this file is the build number (for example, 45 - for build 45) How do I read the contents of the version.txt file into a variable in the batch file?

  2. How do I check if a file ,\\fileserver\myapp\releasedocs\ {build}.doc, exists using the variable from part 1 in place of {build}?

e_i_pi
  • 4,590
  • 4
  • 27
  • 45
user23048345
  • 3,033
  • 7
  • 31
  • 31

4 Answers4

398

Read file contents into a variable:

for /f "delims=" %%x in (version.txt) do set Build=%%x

or

set /p Build=<version.txt

Both will act the same with only a single line in the file, for more lines the for variant will put the last line into the variable, while set /p will use the first.

Using the variable – just like any other environment variable – it is one, after all:

%Build%

So to check for existence:

if exist \\fileserver\myapp\releasedocs\%Build%.doc ...

Although it may well be that no UNC paths are allowed there. Can't test this right now but keep this in mind. Note that with the set /P command the file cannot be in Unicode format.

DomRow
  • 169
  • 3
  • 12
Joey
  • 344,408
  • 85
  • 689
  • 683
  • 9
    The `set` method only reads about 1024 characters, why is that? – Iulian Onofrei Jul 18 '14 at 14:00
  • 15
    Probably due to limits of a buffer within `cmd`. It's a horrible language for reliable scripts. – Joey Jul 18 '14 at 14:03
  • 1
    I know, I struggled for hours to replace a string in a file :| – Iulian Onofrei Jul 18 '14 at 14:04
  • 20
    @IulianOnofrei, `set /p` calls `cmd!ReadBufFromInput` with a stack allocated buffer to read 1023 wide characters (2046 bytes). It reads 1023 bytes from the file, assuming 1 byte per OEM/ANSI character, but it decodes the file using the current codepage, which isn't necessarily OEM/ANSI. Worst case is codepage 65001 and a file filled with 4-byte UTF-8 characters (e.g. an ancient script). You'll get 255 characters, plus a partially decoded character stored as the replacement character, U+FFFD. – Eryk Sun Oct 08 '14 at 23:29
  • 1
    On Windows 10 using the `for` variant gave me the first line of the file as well. – D'Arcy Rittich Nov 10 '15 at 15:29
  • If you want to use a path with spaces for version.txt only second method will work: set /p Build=<"c:\temp\a dir with spaces\version.txt" – Jan Jan 05 '17 at 17:17
  • 3
    @Jan: `for /f "usebackq" %%x in ("path with spaces.txt") ...`. `help for` mentions this, by the way. – Joey Jan 05 '17 at 21:42
  • Can't tell if this works because it results in the `Echo is off` error when trying to output the variable, and using the workaround for _that_ error just prints an empty string. – Dissident Rage Jul 21 '17 at 20:19
  • Dissident Rage: You're probably having another error somewhere in there, or the file you're reading from is empty. – Joey Jul 22 '17 at 06:17
  • @OliverSalzburg: You're having trouble with variable expansion, not with `set /p` not working. – Joey Mar 07 '18 at 14:34
  • Both methods fail for arbitrary Unicode characters. So, for example, if you are using a BAT file to work around https://stackoverflow.com/q/1910275/2279059, this will not work. – Florian Winter Oct 05 '18 at 14:11
  • 2
    Both methods will read the contents of the file as it was when the script was *last* called, not the current content. It's not even the same as what `type version.txt` prints *directly before this*. – ygoe Jul 11 '20 at 16:31
71

You can read multiple variables from file like this:

for /f "delims== tokens=1,2" %%G in (param.txt) do set %%G=%%H

where param.txt:

PARAM1=value1
PARAM2=value2
...
xnagyg
  • 4,784
  • 2
  • 32
  • 24
44

just do:

type version.txt

and it will be displayed as if you typed:

set /p Build=<version.txt
echo %Build%
David
  • 1,636
  • 19
  • 27
29

To get all the lines of the file loaded into the variable, Delayed Expansion is needed, so do the following:

SETLOCAL EnableDelayedExpansion

for /f "Tokens=* Delims=" %%x in (version.txt) do set Build=!Build!%%x

There is a problem with some special characters, though especially ;, % and !

Marc Dingena
  • 556
  • 5
  • 19
DPS
  • 291
  • 3
  • 2