7

I know a way of doing this which is a bit like cheating but the code below creates a temporary file and then deletes it. I don't want that happen. So is there a proper or better way of doing it?

command 2>> "temp"
set /p OUTPUT=<"temp"
del "temp"
echo %OUTPUT%

I know there is a solution which uses for loop but that doesn't work for commands which return more than one line of result. I want to store all of them into my variable. (I tried this code btw)

Community
  • 1
  • 1
ozcanovunc
  • 651
  • 1
  • 8
  • 26
  • The output to a temp file and subsequent `set /p` will only store the first line of whatever is in the temp file to the variable. Is that what you want? Because if that's the case, the `for` loop can be easily adjusted with an `if defined` statement to allow for that. – SomethingDark Jun 24 '15 at 20:07
  • Maybe worth to explicite mention: the desired output of the command is on STDERR. – Stephan Jun 24 '15 at 20:42
  • I want everything to be stored rather than storing the first line if that's possible. – ozcanovunc Jun 25 '15 at 04:46
  • Essentially, it isn't possible to store multiple lines in a single variable. You may be able to store them in an array of variables or you may store them in a single variable with newline replaced by a character or character-string (eg. `line1#line2#line3` where `#` means 'new line`) - but in the latter case, you may need to choose your character carefully and you have a limit of about 8180 characters. – Magoo Jun 25 '15 at 06:20
  • 1
    That would be useful. How do we store them into array of variables? – ozcanovunc Jun 25 '15 at 06:34

2 Answers2

9

You can put it into a single variable with including linefeeds.

setlocal EnableDelayedExpansion
set LF=^


REM The two empty lines are required here
set "output="
for /F "delims=" %%f in ('dir /b') do (
    if defined output set "output=!output!!LF!"
    set "output=!output!%%f"
)
echo !output!

But it can be a bit tricky to handle the data later, because of the embedded linefeeds.
And there is still a limit of 8190 characters per variable.

Often it's easier to use an array.

setlocal EnableDelayedExpansion
set "output_cnt=0"
for /F "delims=" %%f in ('dir /b') do (
    set /a output_cnt+=1
    set "output[!output_cnt!]=%%f"
)
for /L %%n in (1 1 !output_cnt!) DO echo !output[%%n]!
jeb
  • 70,992
  • 15
  • 159
  • 202
0

looks a bit ugly:

for /f "delims=" %%i in ('dir notexistent.xxx  2^>^&1 1^>nul ') do echo %%i

in-depth-explanation here

Community
  • 1
  • 1
Stephan
  • 47,723
  • 10
  • 50
  • 81
  • 1
    That prints everything ok but I want to store them. When I try to set `%%i` into a variable like `do set var=%%i` it stores only the last line. – ozcanovunc Jun 25 '15 at 04:49
  • I modified your loop's body and now that works for the command I'm using but for example it doesn't work for "dir" command. `do ( – ozcanovunc Jun 25 '15 at 06:15
  • 1
    see the [delayed expansion trap](http://stackoverflow.com/a/30284028/2152082). Besides that, a varaible's value can't have linefeeds. `set output=!output!%%i` will concatenate all lines into a one-line-value (you don't need `/p` here and therefore also no ` – Stephan Jun 25 '15 at 07:31
  • @Stephan Why a variable shoudn't have linefeeds included? There is no such limitation – jeb Jun 25 '15 at 09:38
  • 1
    @jeb: correct, but creating and working with such variables is a pain. Variables in batch are simply not designed to have linefeeds, although Implementing them works, with some experience. Using "arrays" should be preferred. – Stephan Jun 25 '15 at 13:26
  • @Stephan From this point of view, you're right. It's not very easy and a little bit error prone – jeb Jun 25 '15 at 19:07
  • @jeb Are you the one who wrote [this batch include library](https://www.reddit.com/r/commandline/comments/jfmmmd/script_transclusion_in_windows_cmdbatch_bat_files/?utm_source=share&utm_medium=web2x&context=3)? – Foad Oct 22 '20 at 20:41
  • 1
    @Foad Yes, please talk in [chat](https://chat.stackoverflow.com/rooms/223508/batch-library) – jeb Oct 23 '20 at 07:55