Set output of a command as a variable (with pipes)

前端 未结 6 1093
花落未央
花落未央 2020-12-01 05:09

Can you redirect the output of a command to a variable with pipes?

I haven\'t tried much as I haven\'t been able to think of anything to try, but I have tried one me

相关标签:
6条回答
  • 2020-12-01 05:32

    You can set the output to a temporary file and the read the data from the file after that you can delete the temporary file.

    echo %date%>temp.txt
    set /p myVarDate= < temp.txt
    echo Date is %myVarDate%
    del temp.txt
    

    In this variable myVarDate contains the output of command.

    0 讨论(0)
  • 2020-12-01 05:36

    Your way can't work for two reasons.

    You need to use set /p text= for setting the variable with user input.
    The other problem is the pipe.
    A pipe starts two asynchronous cmd.exe instances and after finishing the job both instances are closed.

    That's the cause why it seems that the variables are not set, but a small example shows that they are set but the result is lost later.

    set myVar=origin
    echo Hello | (set /p myVar= & set myVar)
    set myVar
    

    Outputs

    Hello
    origin
    

    Alternatives: You can use the FOR loop to get values into variables or also temp files.

    for /f "delims=" %%A in ('echo hello') do set "var=%%A"
    echo %var%
    

    or

    >output.tmp echo Hello
    >>output.tmp echo world
    
    <output.tmp (
      set /p line1=
      set /p line2=
    )
    echo %line1%
    echo %line2%
    

    Alternative with a macro:

    You can use a batch macro, this is a bit like the bash equivalent

    @echo off
    
    REM *** Get version string 
    %$set% versionString="ver"
    echo The version is %versionString[0]%
    
    REM *** Get all drive letters
    `%$set% driveLetters="wmic logicaldisk get name /value | findstr "Name""
    call :ShowVariable driveLetters
    

    The definition of the macro can be found at
    SO:Assign output of a program to a variable using a MS batch file

    0 讨论(0)
  • 2020-12-01 05:40

    In a batch file I usually create a file in the temp directory and append output from a program, then I call it with a variable-name to set that variable. Like this:

    :: Create a set_var.cmd file containing: set %1=
    set /p="set %%1="<nul>"%temp%\set_var.cmd"
    
    :: Append output from a command
    ipconfig | find "IPv4" >> "%temp%\set_var.cmd"
    call "%temp%\set_var.cmd" IPAddress
    echo %IPAddress%
    
    0 讨论(0)
  • 2020-12-01 05:41

    I find myself a tad amazed at the lack of what I consider the best answer to this question anywhere on the internet. I struggled for many years to find the answer. Many answers online come close, but none really answer it. The real answer is

    (cmd & echo.) >2 & (set /p =)<2

    The "secret sauce" being the "closely guarded coveted secret" that "echo." sends a CR/LF (ENTER/new line/0x0D0A). Otherwise, what I am doing here is redirecting the output of the first command to the standard error stream. I then redirect the standard error stream into the standard input stream for the "set /p =" command.

    Example:

    (echo foo & echo.) >2 & (set /p bar=)<2

    0 讨论(0)
  • 2020-12-01 05:46

    The lack of a Linux-like backtick/backquote facility is a major annoyance of the pre-PowerShell world. Using backquotes via for-loops is not at all cosy. So we need kinda of setvar myvar cmd-line command.

    In my %path% I have a dir with a number of bins and batches to cope with those Win shortcomings.

    One batch I wrote is:

    :: setvar varname cmd
    :: Set VARNAME to the output of CMD
    :: Triple escape pipes, eg:
    :: setvar x  dir c:\ ^^^| sort 
    :: -----------------------------
    
    @echo off
    SETLOCAL
    
    :: Get command from argument 
    for /F "tokens=1,*" %%a in ("%*") do set cmd=%%b
    
    :: Get output and set var
    for /F "usebackq delims=" %%a in (`%cmd%`) do (
         ENDLOCAL
         set %1=%%a
    )
    
    :: Show results 
    SETLOCAL EnableDelayedExpansion
    echo %1=!%1! 
    

    So in your case, you would type:

    > setvar text echo Hello
    text=Hello 
    

    The script informs you of the results, which means you can:

    > echo text var is now %text%
    text var is now Hello 
    

    You can use whatever command:

    > setvar text FIND "Jones" names.txt
    

    What if the command you want to pipe to some variable contains itself a pipe?
    Triple escape it, ^^^|:

    > setvar text dir c:\ ^^^| find "Win"
    
    0 讨论(0)
  • 2020-12-01 05:54

    THIS DOESN'T USE PIPEs, but requires a single tempfile
    I used this to put simplified timestamps into a lowtech daily maintenance batfile

    We have already Short-formatted our System-Time to HHmm, (which is 2245 for 10:45PM)
    I direct output of Maint-Routines to logfiles with a $DATE%@%TIME% timestamp;
    . . . but %TIME% is a long ugly string (ex. 224513.56, for down to the hundredths of a sec)

    SOLUTION OVERVIEW:
    1. Use redirection (">") to send the command "TIME /T" everytime to OVERWRITE a temp-file in the %TEMP% DIRECTORY
    2. Then use that tempfile as the input to set a new variable (I called it NOW)
    3. Replace

    echo $DATE%@%TIME% blah-blah-blah >> %logfile%
          with
    echo $DATE%@%NOW% blah-blah-blah >> %logfile%


    ====DIFFERENCE IN OUTPUT:
    BEFORE:
    SUCCESSFUL TIMESYNCH 29Dec14@222552.30
    AFTER:
    SUCCESSFUL TIMESYNCH 29Dec14@2252


    ACTUAL CODE:

    TIME /T > %TEMP%\DailyTemp.txt
    SET /p NOW=<%TEMP%\DailyTemp.txt
    echo $DATE%@%NOW% blah-blah-blah >> %logfile%


    AFTERMATH:
    All that remains afterwards is the appended logfile, and constantly overwritten tempfile. And if the Tempfile is ever deleted, it will be re-created as necessary.

    0 讨论(0)
提交回复
热议问题