批处理 - 将命令输出存储到变量(多行)

Posted

技术标签:

【中文标题】批处理 - 将命令输出存储到变量(多行)【英文标题】:Batch - Store command output to a variable (multiple lines) 【发布时间】:2015-09-11 04:35:51 【问题描述】:

我知道这样做的方法有点像作弊,但下面的代码会创建一个临时文件,然后将其删除。我不希望这种情况发生。那么有没有合适或更好的方法呢?

command 2>> "temp"
set /p OUTPUT=<"temp"
del "temp"
echo %OUTPUT%

我知道有一种使用 for 循环的解决方案,但它不适用于返回多于一行结果的命令。我想将它们全部存储到我的变量中。 (我试过这个code btw)

【问题讨论】:

临时文件的输出和随后的set /p 只会将临时文件中任何内容的第一行存储到变量中。那是你要的吗?因为如果是这种情况,for 循环可以通过 if defined 语句轻松调整以实现这一点。 也许值得一提:命令的期望输出在 STDERR 上。 如果可能的话,我希望存储所有内容,而不是存储第一行。 本质上,不可能在一个变量中存储多行。您可以将它们存储在变量数组中,或者您可以将它们存储在单个变量中,换行符替换为字符或字符串(例如line1#line2#line3,其中# 表示“新行”) - 但在后一种情况,您可能需要仔细选择您的字符,并且您有大约 8180 个字符的限制。 那会很有用。我们如何将它们存储到变量数组中? 【参考方案1】:

您可以将它放入一个包含换行符的变量中。

setlocal EnableDelayedExpansion
set LF=^


REM The two empty lines are required here
set "output="
for /F "delims=" %%f in ('dir /b') do (
    if defined output set "output=!output!!LF!"
    set "output=!output!%%f"
)
echo !output!

但由于嵌入了换行符,以后处理数据可能有点棘手。 每个变量仍然有 8191 个字符的限制。

通常使用数组更容易。

setlocal EnableDelayedExpansion
set "output_cnt=0"
for /F "delims=" %%f in ('dir /b') do (
    set /a output_cnt+=1
    set "output[!output_cnt!]=%%f"
)
for /L %%n in (1 1 !output_cnt!) DO echo !output[%%n]!

【讨论】:

两者都有效,但我也更喜欢第二个。谢谢!【参考方案2】:

看起来有点丑:

for /f "delims=" %%i in ('dir notexistent.xxx  2^>^&1 1^>nul ') do echo %%i

深入解释here

【讨论】:

打印一切正常,但我想存储它们。当我尝试将%%i 设置为do set var=%%i 之类的变量时,它只存储最后一行。 我修改了你的循环体,现在它适用于我正在使用的命令,但例如它不适用于“dir”命令。 do ( &lt;nul set /p "output=%output%%%i" ) 见delayed expansion trap。除此之外,变量的值不能有换行符。 set output=!output!%%i 将所有行连接成一个单行值(这里不需要/p,因此也不需要&lt;nul @jeb:正确,但是创建和使用这些变量是一件痛苦的事情。批量变量根本不是为了换行而设计的,尽管实现它们是可行的,但有一些经验。应该首选使用“数组”。 @Foad 是的,请在chat谈

以上是关于批处理 - 将命令输出存储到变量(多行)的主要内容,如果未能解决你的问题,请参考以下文章

为啥将命令输出定向到变量在批处理文件中不起作用

将 curl 输出存储在变量批处理脚本中

使用管道将 Windows 命令解析为批处理文件中的变量 [重复]

使用Windows命令行将多行环境变量回显到文本文件

将 powershell 输出存储在 CMD 中的变量中

批处理文件命令输出到名称中带有日期和时间的文件中[重复]