3
set var1=Demo
set var2=%var1%
echo %var2%
rem Output:Demo

Why does set var2 below not work if in one line with set var1?

set var1=& set var2=
set var1=Demo& set var2=%var1%
echo %var2%
rem output:%var1%

How can I set var2 from var1 in one line?

3 Answers 3

3

Why doesn't set var2 work if in one line with set var1?

As harrymc points out:

The variable substitution is done on the whole command-line before the line is executed. At that time, the var1 variable is not yet defined.

You can get around this limitation using delayed expansion:

@echo off
setlocal enabledelayedexpansion
set var1=Demo & set var2=!var1!
echo %var2%
endlocal

Example:

F:\test>test
Demo

Further Reading

3
  • Thanks. So. No other way except with delayed on ?
    – Mr.Key7
    Commented Mar 31 at 17:42
  • No other way ...
    – DavidPostill
    Commented Mar 31 at 18:02
  • I like ss64.com website. I copy most menus guide to excel and create powershell script with module ImportExcel to open each guide of ss64 though Powershell
    – Mr.Key7
    Commented Mar 31 at 18:19
3

The variable substitution is done on the whole command-line before the line is executed. At that time, the var1 variable is not yet defined.

The rules for an undefined variable substitution are:

  • If the variable is entered interactively, no substitution is done and the text stays as %var1%
  • If used in a batch file, the variable is replaced by a null string.

You need to break this one-liner into two lines in order for var1 to have a value. Or see answer by @DavidPostill.

2
  • Wrong. Delayed expansion will fix the one liner
    – DavidPostill
    Commented Mar 31 at 16:48
  • 1
    @DavidPostill: Not wrong if it explains the problem, you even quoted me. But why downvote me? I added a pointer to your answer.
    – harrymc
    Commented Mar 31 at 17:07
2

You can do this without using Delayed Expansion (without "setlocal enabledelayedexpansion"), by using a "for" (loop) with "call".

@echo off
set "var1=" & set "var2="
echo var1=[%var1%], var2=[%var2%]

:rem The one-liner: 
set "var1=Demo" & for /f "usebackq delims=" %%a in (`call echo ^%var1^%`) do @set "var2=%%a"
:: 

echo var1=[%var1%], var2=[%var2%]
:end

The output:

var1=[], var2=[]
var1=[Demo], var2=[Demo]

You can even add a second "for" loop to do the "echo var2" in the same line:

:rem The one-liner: 
set "var1=Demo" & for /f "usebackq delims=" %%a in (`call echo ^%var1^%`) do @set "var2=%%a" & for /f "usebackq delims=" %%a in (`call echo var2^=[^%var2^%]`) do @echo %%a
:: 
:end

The "Final" output:

var2=[Demo]

Here's the breakdown of the "for" and "call":

for /f "usebackq" %%a    Operates on a command that is enclosed in `backquotes`. 
                         Executes that command and captures the output of that 
                         command into variable %%a. 

"delims="                Disables all delimiters when parsing the command 
                         output. Default delimiters are "space" and "tab". 
                         Not required for this specific example. 
                         Used when the command output might contain delimiters. 

(`call echo ^%var1^%`) 
(`call echo var2^=[^%var2^%]`) 
                         Use "call" to execute the echo command within a 
                         separate process. 

                         "^" escapes special characters like "%" and "=" when 
                         the command is read by "for". 

 do @set "var2=%%a" 
 do @echo %%a            Sets the variable "var2" from the output of the 
                         command in the for loop. 


                         In this case, the for command will execute just once. 

                         If the output of the command spanned multiple lines, 
                         the for command would execute once for each non-empty 
                         output line. 
4
  • I tried. Not work in my PC. Win10, Console wt.exe. Output: Echo on
    – Mr.Key7
    Commented Apr 1 at 10:32
  • 'var1=[Demo], var2=[ECHO is on.]'
    – Mr.Key7
    Commented Apr 1 at 10:33
  • 1
    set var1=Demo&call set var2=%%var1%% suffices.
    – Neil
    Commented Apr 1 at 21:16
  • @Neil. Your code simples and work properly with no delayed on
    – Mr.Key7
    Commented Apr 4 at 12:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .