将命令输出设置为变量(带管道)

时间:2013-02-19 07:43:52

标签: batch-file

您可以将命令的输出重定向到带管道的变量吗?

我没有尝试太多,因为我没有想到任何可以尝试的东西,但我尝试过一种方法(有两种变化)......

例如:

echo Hello|set text=

没有用,也没有:

echo Hello | set text=

我知道你可以使用FOR命令轻松地做到这一点,但我认为使用管道看起来会更“好”。

如果你想知道,我没有特别的理由我问这个,除了我很好奇,我找不到答案。

6 个答案:

答案 0 :(得分:44)

你的方式不能有两个原因。

您需要使用set /p text=通过用户输入设置变量 另一个问题是管道 管道启动两个异步cmd.exe实例,完成作业后,两个实例都将关闭。

这就是为什么似乎没有设置变量的原因,但是一个小例子显示它们已设置但结果稍后丢失。

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

输出

Hello
origin

替代方案:您可以使用FOR循环将值输入变量或临时文件。

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

>output.tmp echo Hello
>>output.tmp echo world

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

替代宏:

你可以使用批量宏,这有点像bash等价物

@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

宏的定义可以在
找到 SO:Assign output of a program to a variable using a MS batch file

答案 1 :(得分:13)

缺乏类似Linux的backtick/backquote工具是PowerShell前世界的主要烦恼。通过for循环使用反引号并不是很舒适。所以我们需要setvar myvar cmd-line命令。

在我的%path%我有一个带有许多箱子和批次的目录,以应对那些胜利的缺点。

我写的一个批次是:

:: 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! 

因此,在您的情况下,您可以输入:

> setvar text echo Hello
text=Hello 

脚本会通知您结果,这意味着您可以:

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

您可以使用任何命令:

> setvar text FIND "Jones" names.txt

如果要管道到某个变量的命令包含管道,该怎么办? 三倍逃避它,^^^|

> setvar text dir c:\ ^^^| find "Win"

答案 2 :(得分:4)

这不使用PIPE,但需要一个临时文件 我用它将简化的时间戳放入低技术日常维护蝙蝠文件中
我们已经将系统时间短格式化为HHmm(在下午10:45为2245) 我将Maint-Routines的输出定向到具有$ DATE%@%TIME%时间戳的日志文件;
。 。 。但%TIME%是一个长丑陋的字符串(例如224513.56,低至百分之一秒)

解决方案概述:
1.使用重定向(“&gt;”)每次发送命令“TIME / T”到OVERWRITE%TEMP%DIRECTORY中的临时文件
2.然后使用该tempfile作为输入来设置一个新变量(我现在称之为) 3.替换

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


====输出差异:
之前:
SUCCESSFUL TIMESYNCH 29Dec14@222552.30
之后:
SUCCESSFUL TIMESYNCH 29Dec14@2252


实际代码:

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


AFTERMATH:
之后剩下的就是附加的日志文件,并不断覆盖tempfile。如果Tempfile被删除,将根据需要重新创建。

答案 3 :(得分:2)

在批处理文件中,我通常在temp目录中创建一个文件 追加程序的输出,然后我称之为 使用变量名来设置该变量。 像这样:

:: 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%

答案 4 :(得分:0)

我发现自己对互联网上任何地方都缺少对这个问题的最佳答案感到惊讶。我奋斗了很多年才找到答案。在线上有很多答案,但没有一个能真正回答。真正的答案是

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

“秘密调味料”是“回声”的“密密的令人垂涎的秘密”。发送CR / LF(ENTER /换行/ 0x0D0A)。否则,我在这里所做的就是将第一个命令的输出重定向到标准错误流。然后,我将标准错误流重定向到“ set / p =“命令”的标准输入流中。

示例:

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

答案 5 :(得分:-1)

您可以将输出设置为临时文件,然后从文件中读取数据,之后您可以删除临时文件。

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

在此变量&#34; myVarDate &#34;包含命令的输出