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

前端 未结 9 1455
我在风中等你
我在风中等你 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%
    

提交回复
热议问题