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

BDM*_*BDM 46 batch-file

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

我没有尝试太多,因为我没有想到任何尝试,但我尝试了一种方法(有两种变化)......

例如:

echo Hello|set text=
Run Code Online (Sandbox Code Playgroud)

没有工作,也没有:

echo Hello | set text=
Run Code Online (Sandbox Code Playgroud)

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

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

jeb*_*jeb 44

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

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

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

set myVar=origin
echo Hello | (set /p myVar= & set myVar)
set myVar
Run Code Online (Sandbox Code Playgroud)

输出

Hello
origin
Run Code Online (Sandbox Code Playgroud)

替代方案:您可以使用FOR循环将值获取到变量或临时文件中.

for /f "delims=" %%A in ('echo hello') do set "var=%%A"
echo %var%
Run Code Online (Sandbox Code Playgroud)

要么

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

<output.tmp (
  set /p line1=
  set /p line2=
)
echo %line1%
echo %line2%
Run Code Online (Sandbox Code Playgroud)

  • 那么,没有临时文件或"for"命令,没有办法解决这些限制?即使没有,也谢谢. (3认同)
  • 顺便说一句,在我的测试中,您只能在 for 语句中使用 1 个命令。您不能将更多命令与 &amp; 链接在一起。 (2认同)

ant*_*nio 13

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

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

我写的一个批次是:

:: 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! 
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下,你会输入:

> setvar text echo Hello
text=Hello 
Run Code Online (Sandbox Code Playgroud)

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

> echo text var is now %text%
text var is now Hello 
Run Code Online (Sandbox Code Playgroud)

你可以使用任何命令:

> setvar text FIND "Jones" names.txt
Run Code Online (Sandbox Code Playgroud)

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

> setvar text dir c:\ ^^^| find "Win"
Run Code Online (Sandbox Code Playgroud)


小智 10

我发现自己有点惊讶,因为在互联网上的任何地方都没有我认为对这个问题的最佳答案。我挣扎了很多年才找到答案。网上很多答案都很接近,但没有一个真正回答这个问题。真正的答案是

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

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

例子:

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

  • 很抱歉破坏了你的梦想,但这不能通过 STDERR 工作,而是通过名为“2”的文件(用“dir”检查) (6认同)

小智 6

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

echo %date%>temp.txt
set /p myVarDate= < temp.txt
echo Date is %myVarDate%
del temp.txt
Run Code Online (Sandbox Code Playgroud)

该变量myVarDate包含命令的输出。

  • 已经有 3 个旧答案提到了临时文件。我看不出您的回答有任何进一步的好处? (6认同)

Zip*_*zel 5

这不使用管道,但需要一个临时文件
我用它来将简化的时间戳放入一个低技术的日常维护 batfile

我们已经将我们的系统时间短格式为 HHmm,(晚上 10:45 为 2245)
我直接输出维护程序到带有 $DATE%@%TIME% 时间戳的日志文件;
. . . 但 %TIME% 是一个长而难看的字符串(例如 224513.56,下降到百分之一秒)

解决方案概述:
1. 每次使用重定向 (">") 发送命令 "TIME /T" 以覆盖 %TEMP% 目录中的临时文件
2. 然后使用该临时文件作为输入来设置新变量(我立即调用)
3. 替换

回声 $DATE%@%TIME% blah-blah-blah >> %logfile%
      和
回声 $DATE%@%NOW% blah-blah-blah >> %logfile%


====输出差异:
之前:
成功的时间同步 29Dec14@222552.30
后:
成功的时间同步 29Dec14@2252


实际代码:

时间 /T > %TEMP%\DailyTemp.txt
SET /p 现在=<%TEMP%\DailyTemp.txt
回声 $DATE%@%NOW% blah-blah-blah >> %logfile%


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


归档时间:

查看次数:

153909 次

最近记录:

6 年,11 月 前