How to set commands output as a variable in a batch file

前端 未结 9 1264
我在风中等你
我在风中等你 2020-11-22 01:19

Is it possible to set a statement\'s output of a batch file to a variable, for example:

findstr testing > %VARIABLE%

echo %VARIABLE%
相关标签:
9条回答
  • 2020-11-22 01:39

    Some notes and some tricks.

    The 'official' way to assign result to a variable is with FOR /F though in the other answers is shown how a temporary file can be used also.

    For command processing FOR command has two forms depending if the usebackq option is used. In the all examples below the whole output is used without splitting it.

    FOR /f "tokens=* delims=" %%A in ('whoami') do @set "I-Am=%%A"
    FOR /f "usebackq tokens=* delims=" %%A in (`whoami`) do @set "I-Am=%%A"
    

    and if used directly in the console"

    FOR /f "tokens=* delims=" %A in ('whoami') do set "I-Am=%A"
    FOR /f "usebackq tokens=* delims=" %A in (`whoami`) do set "I-Am=%A"
    

    %%A is a temporary variable available only on the FOR command context and is called token.The two forms can be useful in case when you are dealing with arguments containing specific quotes. It is especially useful with REPL interfaces of other languages or WMIC. Though in both cases the expression can be put in double quotes and it still be processed.

    Here's an example with python (it is possible to transition the expression in the brackets on a separate line which is used for easier reading):

    @echo off
    
    for /f "tokens=* delims=" %%a in (
      '"python -c ""print("""Message from python""")"""'
    ) do (
        echo processed message from python: "%%a"
    )
    

    To use an assigned variable in the same FOR block check also the DELAYED EXPANSION

    And some tricks

    To save yourself from writing all the arguments for the FOR command you can use MACRO for assigning the result to variable:

    @echo off
    
    ::::: ---- defining the assign macro ---- ::::::::
    setlocal DisableDelayedExpansion
    (set LF=^
    %=EMPTY=%
    )
    set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
    
    ::set argv=Empty
    set assign=for /L %%n in (1 1 2) do ( %\n%
       if %%n==2 (%\n%
          setlocal enableDelayedExpansion%\n%
          for /F "tokens=1,2 delims=," %%A in ("!argv!") do (%\n%
             for /f "tokens=* delims=" %%# in ('%%~A') do endlocal^&set "%%~B=%%#" %\n%
          ) %\n%
       ) %\n%
    ) ^& set argv=,
    
    ::::: -------- ::::::::
    
    
    :::EXAMPLE
    %assign% "WHOAMI /LOGONID",result
    echo %result%
    

    the first argument to the macro is the command and the second the name of the variable we want to use and both are separated by , (comma). Though this is suitable only for straight forward scenarios.

    If we want a similar macro for the console we can use DOSKEY

    doskey assign=for /f "tokens=1,2 delims=," %a in ("$*") do @for /f "tokens=* delims=" %# in ('"%a"') do @set "%b=%#"
    rem  -- example --
    assign WHOAMI /LOGONID,my-id
    echo %my-id%
    

    DOSKEY does accept double quotes as enclosion for arguments so this also is useful for more simple scenarios.

    FOR also works well with pipes which can be used for chaining commands (though it is not so good for assigning a variable.

    hostname |for /f "tokens=* delims=" %%# in ('more') do @(ping %%#)
    

    Which also can be beautified with macros:

    @echo off
    :: --- defining chain command macros ---
    set "result-as-[arg]:=|for /f "tokens=* delims=" %%# in ('more') do @("
    set "[arg]= %%#)"
    :::  --------------------------  :::
    
    ::Example:
    hostname %result-as-[arg]:% ping %[arg]%
    

    And for completnes macros for the temp file approach (no doskey definition ,but it also can be easy done.If you have a SSD this wont be so slow):

    @echo off
    
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    set "[[=>"#" 2>&1&set/p "&set "]]==<# & del /q # >nul 2>&1"
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    chcp %[[%code-page%]]%
    echo ~~%code-page%~~
    
    whoami %[[%its-me%]]%
    echo ##%its-me%##
    

    For /f with another macro:

    ::::::::::::::::::::::::::::::::::::::::::::::::::
    ;;set "{{=for /f "tokens=* delims=" %%# in ('" &::
    ;;set "--=') do @set ""                        &::
    ;;set "}}==%%#""                               &::
    ::::::::::::::::::::::::::::::::::::::::::::::::::
    
    :: --examples
    
    ::assigning ver output to %win-ver% variable
    %{{% ver %--%win-ver%}}%
    echo 3: %win-ver%
    
    
    ::assigning hostname output to %my-host% variable
    %{{% hostname %--%my-host%}}%
    echo 4: %my-host%
    
    0 讨论(0)
  • 2020-11-22 01:41

    I found this thread on that there Interweb thing. Boils down to:

    @echo off 
    setlocal enableextensions 
    for /f "tokens=*" %%a in ( 
    'VER' 
    ) do ( 
    set myvar=%%a 
    ) 
    echo/%%myvar%%=%myvar% 
    pause 
    endlocal 
    

    You can also redirect the output of a command to a temporary file, and then put the contents of that temporary file into your variable, likesuchashereby. It doesn't work with multiline input though.

    cmd > tmpFile 
    set /p myvar= < tmpFile 
    del tmpFile 
    

    Credit to the thread on Tom's Hardware.

    0 讨论(0)
  • 2020-11-22 01:44

    in a single line:

    FOR /F "tokens=*" %%g IN ('*your command*') do (SET VAR=%%g)
    

    the command output will be set in %g then in VAR.

    More informations: https://ss64.com/nt/for_cmd.html

    0 讨论(0)
  • 2020-11-22 01:44

    These answers were all so close to the answer that I needed. This is an attempt to expand on them.

    In a Batch file

    If you're running from within a .bat file and you want a single line that allows you to export a complicated command like jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json to a variable named AWS_ACCESS_KEY then you want this:

    FOR /F "tokens=* USEBACKQ" %%g IN (`jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json`) do (SET "AWS_ACCESS_KEY=%%g")
    

    On the Command Line

    If you're at the C:\ prompt you want a single line that allows you to run a complicated command like jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json to a variable named AWS_ACCESS_KEY then you want this:

    FOR /F "tokens=* USEBACKQ" %g IN (`jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json`) do (SET "AWS_ACCESS_KEY=%g")
    

    Explanation

    The only difference between the two answers above is that on the command line, you use a single % in your variable. In a batch file, you have to double up on the percentage signs (%%).

    Since the command includes colons, quotes, and parentheses, you need to include the USEBACKQ line in the options so that you can use backquotes to specify the command to run and then all kinds of funny characters inside of it.

    0 讨论(0)
  • 2020-11-22 01:50
    cd %windir%\system32\inetsrv
    
    @echo off
    
    for /F "tokens=* USEBACKQ" %%x in (      
            `appcmd list apppool /text:name`
           ) do (
                echo|set /p=  "%%x - " /text:name & appcmd.exe list apppool "%%x" /text:processModel.identityType
           )
    
    echo %date% & echo %time%
    
    pause
    
    0 讨论(0)
  • 2020-11-22 01:52
    FOR /F "tokens=* USEBACKQ" %%F IN (`command`) DO (
    SET var=%%F
    )
    ECHO %var%
    

    I always use the USEBACKQ so that if you have a string to insert or a long file name, you can use your double quotes without screwing up the command.

    Now if your output will contain multiple lines, you can do this

    SETLOCAL ENABLEDELAYEDEXPANSION
    SET count=1
    FOR /F "tokens=* USEBACKQ" %%F IN (`command`) DO (
      SET var!count!=%%F
      SET /a count=!count!+1
    )
    ECHO %var1%
    ECHO %var2%
    ECHO %var3%
    ENDLOCAL
    
    0 讨论(0)
提交回复
热议问题