37

I need to be able to load the entire contents of a text file and load it into a variable for further processing.

How can I do that?


Here's what I did thanks to Roman Odaisky's answer.

SetLocal EnableDelayedExpansion
set content=
for /F "delims=" %%i in (test.txt) do set content=!content! %%i

echo %content%
EndLocal
Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
Keng
  • 52,011
  • 32
  • 81
  • 111
  • You might benefit (either directly and immediately or indirectly and at a later time) by reading this page (easy read. clear and concise). [Getting File Data into an Environment Variable (env var)](http://www.pement.org/sed/bat_env.htm) I was able to have success with "method 4b", which gives me hope that I will eventually have success with 4a. – pestophagous Sep 25 '08 at 16:53

7 Answers7

51

If your set command supports the /p switch, then you can pipe input that way.

set /p VAR1=<test.txt
set /? |find "/P"

The /P switch allows you to set the value of a variable to a line of input entered by the user. Displays the specified promptString before reading the line of input. The promptString can be empty.

This has the added benefit of working for un-registered file types (which the accepted answer does not).

phuclv
  • 37,963
  • 15
  • 156
  • 475
Will Bickford
  • 5,381
  • 2
  • 30
  • 45
  • 1
    Can you please explain `set /? |find "/P"`? – aliteralmind Nov 29 '14 at 19:33
  • 1
    I'm piping the output of the 'set /?' command into the find command and then looking for lines with "/P" in them. Try looking at set /? output on its own to see. – Will Bickford Dec 01 '14 at 16:34
  • 24
    It should be noted this method only captures the first line of "test.txt". It does not set VAR1 to the entire contents of the file. – DrStrangepork May 22 '15 at 01:24
  • Right. Then I'm not sure why this was so upvoted as it clearly doesn't answer the original question as he wanted the "entire" contents of the file read into the variable. Very misleading answer. – stigzler Feb 13 '23 at 21:24
17

Use for, something along the lines of:

set content=
for /f "delims=" %%i in ('filename') do set content=%content% %%i

Maybe you’ll have to do setlocal enabledelayedexpansion and/or use !content! rather than %content%. I can’t test, as I don’t have any MS Windows nearby (and I wish you the same :-).

The best batch-file-black-magic-reference I know of is at http://www.rsdn.ru/article/winshell/batanyca.xml. If you don’t know Russian, you still could make some use of the code snippets provided.

Roman Odaisky
  • 2,811
  • 22
  • 26
  • 2
    One really annoying part of this is that Windows needs to have an associated file type for the 'filename' parameter above. Your script will block on a window prompt if you try using an un-registered file type. – Will Bickford Jan 31 '13 at 20:11
  • `For` manual is available here : [FOR /F](http://ss64.com/nt/for_f.html) – Flows Jun 15 '16 at 15:12
  • 1
    All this does is open up the file for me. – Trevor Hickey Jan 23 '17 at 13:41
  • That only put the las line in the varable. final result: `content=%content%lastline`. Notice that the `%content%` is not interpreted. – Jérémy Sep 24 '19 at 14:35
2

Can you define further processing?

You can use a for loop to almost do this, but there's no easy way to insert CR/LF into an environment variable, so you'll have everything in one line. (you may be able to work around this depending on what you need to do.)

You're also limited to less than about 8k text files this way. (You can't create a single env var bigger than around 8k.)

Bill's suggestion of a for loop is probably what you need. You process the file one line at a time:

(use %i at a command line %%i in a batch file)

for /f "tokens=1 delims=" %%i in (file.txt) do echo %%i

more advanced:

for /f "tokens=1 delims=" %%i in (file.txt) do call :part2 %%i
goto :fin

:part2
echo %1
::do further processing here
goto :eof

:fin
Flexo
  • 87,323
  • 22
  • 191
  • 272
2

You can use:

set content=
for /f "delims=" %%i in ('type text.txt') do set content=!content! %%i
Curro
  • 832
  • 2
  • 10
  • 14
2

To read in an entire multi-line file but retain newlines, you must reinsert them. The following (with '<...>' replaced with a path to my file) did the trick:

@echo OFF
SETLOCAL EnableDelayedExpansion
set N=^


REM These two empty lines are required
set CONTENT=
set FILE=<...>
for /f "delims=" %%x in ('type %FILE%') do set "CONTENT=!CONTENT!%%x!N!"
echo !CONTENT!

ENDLOCAL

You would likely want to do something else rather than echo the file contents.

Note that there is likely a limit to the amount of data that can be read this way so your mileage may vary.

Erik Erikson
  • 418
  • 4
  • 9
0

Create a file called "SetFile.bat" that contains the following line with no carriage return at the end of it...

set FileContents=

Then in your batch file do something like this...

   @echo off
   copy SetFile.bat + %1 $tmp$.bat > nul
   call $tmp$.bat
   del $tmp$.bat

%1 is the name of your input file and %FileContents% will contain the contents of the input file after the call. This will only work on a one line file though (i.e. a file containing no carriage returns). You could strip out/replace carriage returns from the file before calling the %tmp%.bat if needed.

pdavis
  • 3,212
  • 2
  • 29
  • 31
0
for /f "delims=" %%i in (count.txt) do set c=%%i
echo %c%
pause
clichok
  • 11
  • 1