如何将命令输出设置为批处理文件中的变量

Den*_*nis 207 windows batch-file

是否可以将批处理文件的语句输出设置为变量,例如:

findstr testing > %VARIABLE%

echo %VARIABLE%
Run Code Online (Sandbox Code Playgroud)

Mec*_*ash 252

FOR /F "tokens=* USEBACKQ" %%F IN (`command`) DO (
SET var=%%F
)
ECHO %var%
Run Code Online (Sandbox Code Playgroud)

我总是使用USEBACKQ,这样如果你有一个要插入的字符串或一个长文件名,你可以使用双引号而不用搞砸命令.

现在,如果输出包含多行,则可以执行此操作

SETLOCAL ENABLEDELAYEDEXPANSION
SET count=1
FOR /F "tokens=* USEBACKQ" %%F IN (`command`) DO (
  SET var!count!=%%F
  SET /a count=!count!+1
)
ECHO %var1%
ECHO %var2%
ECHO %var3%
ENDLOCAL
Run Code Online (Sandbox Code Playgroud)

  • @MattVukomanovic它适用于我使用`^ |`代替`|`,如[here](/sf/answers/7595801/)所述 (4认同)
  • 这一点真的很聪明: `SET var!count!=%%F` 我以前没有在批处理文件中见过动态变量名。 (4认同)
  • 在Win7系统中为我工作,谢谢!(是的,这是7年的实用性)PS不要忘记在命令中将%扩展到%%! (3认同)

dol*_*phy 62

我在Interweb上发现了这个帖子.归结为:

@echo off 
setlocal enableextensions 
for /f "tokens=*" %%a in ( 
'VER' 
) do ( 
set myvar=%%a 
) 
echo/%%myvar%%=%myvar% 
pause 
endlocal 
Run Code Online (Sandbox Code Playgroud)

您还可以将命令的输出重定向到临时文件,然后将该临时文件的内容放入您的变量中,likeuchashereby:

cmd > tmpFile 
set /p myvar= < tmpFile 
del tmpFile 
Run Code Online (Sandbox Code Playgroud)

感谢汤姆硬件上的线程.

  • 使用临时文件真的很有用的技巧. (4认同)
  • 底部方法(在所有其他方式中都更可取)的唯一缺点是,它不适用于多行输出。 (2认同)
  • 你是likesuchashereby的第二个结果 - https://imagebin.ca/v/4NPSlQFgifce (2认同)
  • 您的第二个示例极大地帮助了我编写批处理文件来检查 chromedriver.exe 的版本与包含版本号的文本文件。我是一个老 DOS 恐龙,不知道 set 命令的开关。其他的东西对我来说太过分了。 (2认同)

Yur*_*uri 37

在一行中:

FOR /F "tokens=*" %g IN ('*your command*') do (SET VAR=%g)
Run Code Online (Sandbox Code Playgroud)

命令输出将在%g中设置,然后在VAR中设置.

更多信息:https://ss64.com/nt/for_cmd.html

  • 我的批次没有以"%g"运行.它以"%% g"运行. (14认同)
  • + Santiago Villafuerte:是的,如果您是从批处理文件运行,但是如果您想自己从命令行运行它(例如:在将其放入批处理文件之前进行测试),那么您使用单个%. (4认同)

小智 17

要读取文件......

set /P Variable=<File.txt
Run Code Online (Sandbox Code Playgroud)

写文件

@echo %DataToWrite%>File.txt
Run Code Online (Sandbox Code Playgroud)

注意; 在<>字符之前有空格导致在变量的末尾添加空格

要添加到文件(如记录器程序),首先要在其中创建一个名为e.txt的单个回车键的文件

set /P Data=<log0.log
set /P Ekey=<e.txt
@echo %Data%%Ekey%%NewData%>log0.txt
Run Code Online (Sandbox Code Playgroud)

你的日志看起来像这样

Entry1
Entry2 
Run Code Online (Sandbox Code Playgroud)

等等

无论如何有几件有用的东西


npo*_*aka 12

一些笔记和一些技巧。

FOR /F尽管在其他答案中显示了如何使用临时文件,但将结果分配给变量的“官方”方法是使用。

FOR根据是否使用usebackq选项,命令处理命令有两种形式。在下面的所有示例中,使用整个输出而不对其进行拆分。

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

如果直接在控制台中使用:

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

%%A是一个仅在FOR命令上下文中可用的临时变量,称为 token。这两种形式在您处理包含特定引号的参数时非常有用。它对于其他语言或 WMIC 的 REPL 接口特别有用。尽管在这两种情况下,表达式都可以放在双引号中,但仍会被处理。

这是一个使用 python 的示例(可以将括号中的表达式转换为单独的一行,以便于阅读):

@echo off

for /f "tokens=* delims=" %%a in (
  '"python -c ""print("""Message from python""")"""'
) do (
    echo processed message from python: "%%a"
)
Run Code Online (Sandbox Code Playgroud)

要在同一个FOR块中使用分配的变量,还要检查DELAYED EXPANSION

还有一些小技巧

为了避免为 FOR 命令编写所有参数,您可以使用MACRO将结果分配给变量:

@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%
Run Code Online (Sandbox Code Playgroud)

宏的第一个参数是命令,第二个参数是我们要使用的变量的名称,两者都用,(逗号)分隔。虽然这仅适用于直接的场景。

如果我们想要一个类似的控制台宏,我们可以使用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%
Run Code Online (Sandbox Code Playgroud)

DOSKEY 确实接受双引号作为参数的括号,因此这对于更简单的场景也很有用。

FOR 也适用于可用于链接命令的管道(尽管它不太适合分配变量。

hostname |for /f "tokens=* delims=" %%# in ('more') do @(ping %%#)
Run Code Online (Sandbox Code Playgroud)

也可以用宏美化:

@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]%
Run Code Online (Sandbox Code Playgroud)

对于临时文件方法的完整宏(没有 doskey 定义,但它也很容易完成。如果你有一个 SSD,这不会那么慢):

@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%##
Run Code Online (Sandbox Code Playgroud)

对于带有另一个宏的 /f:

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


Rya*_*ton 11

这些答案都非常接近我需要的答案。这是对它们进行扩展的尝试。

在批处理文件中

如果您是从.bat文件中运行的,并且希望使用一行来将复杂的命令导出jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json到名为的变量,AWS_ACCESS_KEY那么您需要这样做:

FOR /F "tokens=* USEBACKQ" %%g IN (`jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json`) do (SET "AWS_ACCESS_KEY=%%g")
Run Code Online (Sandbox Code Playgroud)

在命令行上

如果出现C:\提示,则只需要一行就可以运行一个复杂的命令,例如jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json对名为的变量的操作,AWS_ACCESS_KEY那么您需要这样做:

FOR /F "tokens=* USEBACKQ" %g IN (`jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json`) do (SET "AWS_ACCESS_KEY=%g")
Run Code Online (Sandbox Code Playgroud)

说明

上面两个答案之间的唯一区别是,在命令行上,您在变量中使用了一个%。在批处理文件中,您必须加倍百分号(%%)。

由于该命令包含冒号,引号和括号,因此您需要USEBACKQ在选项中包括该行,以便可以使用反引号指定要运行的命令,然后在其中使用各种有趣的字符。


Zim*_*mba 6

如果您不想输出到临时文件然后读入变量,则此代码将命令结果直接存储到变量中:

FOR /F %i IN ('findstr testing') DO set VARIABLE=%i
echo %VARIABLE%
Run Code Online (Sandbox Code Playgroud)

如果要将搜索字符串用双引号引起来:

FOR /F %i IN ('findstr "testing"') DO set VARIABLE=%i
Run Code Online (Sandbox Code Playgroud)

如果要将此代码存储在批处理文件中,请添加一个额外的%符号:

FOR /F %%i IN ('findstr "testing"') DO set VARIABLE=%%i
Run Code Online (Sandbox Code Playgroud)

一个有用的示例,用于计算目录中文件的数量并存储在变量中:(说明管道)

FOR /F %i IN ('dir /b /a-d "%cd%" ^| find /v /c "?"') DO set /a count=%i
Run Code Online (Sandbox Code Playgroud)

注意使用单引号,而不是在命令括号双引号“或重音符'的,这是更清洁的替代delimstokensusebackqfor循环。

在Win 10 CMD上测试。


归档时间:

查看次数:

410348 次

最近记录:

6 年,1 月 前