windows 如何将命令输出设置为批处理文件中的变量[重复]

edqdpe6u  于 2023-04-07  发布在  Windows
关注(0)|答案(9)|浏览(288)

此问题已在此处有答案

Assign output of a program to a variable using a MS batch file(12个回答)
11个月前关闭。
是否可以将批处理文件的语句输出设置为变量,例如:

findstr testing > %VARIABLE%

echo %VARIABLE%
zxlwwiss

zxlwwiss1#

FOR /F "tokens=* USEBACKQ" %%F IN (`command`) DO (
SET var=%%F
)
ECHO %var%

我总是使用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
u91tlkcl

u91tlkcl2#

在一行中:

FOR /F "tokens=*" %%g IN ('your command') do (SET VAR=%%g)

命令输出将以%g设置,然后以VAR设置。
更多信息:https://ss64.com/nt/for_cmd.html

kulphzqa

kulphzqa3#

我在网上找到了this thread。归结为:

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

你也可以将命令的输出重定向到一个临时文件,然后将该临时文件的内容放入你的变量中,就像这样。

cmd > tmpFile 
set /p myvar= < tmpFile 
del tmpFile

这是Tom's Hardware上的一个帖子。

sshcrbum

sshcrbum4#

如果你不想输出到一个临时文件,然后读入一个变量,这段代码将命令的结果直接存储到一个变量中:

FOR /F %i IN ('findstr testing') DO set VARIABLE=%i
echo %VARIABLE%

如果要将搜索字符串括在双引号中:

FOR /F %i IN ('findstr "testing"') DO set VARIABLE=%i

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

FOR /F %%i IN ('findstr "testing"') DO set VARIABLE=%%i

一个有用的例子来计算目录中的文件数量&存储在变量中:(图示管道)

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

请注意,在命令括号中使用单引号而不是双引号“或重音符。这是for循环中delimstokensusebackq`的更清晰的替代方案。

更新27/8/2021:

另一种方法是设置errorlevel变量,尽管许多人不鼓励在大型脚本上使用setting errorlevel,或者在新安装的操作系统变体的cmd版本中使用setting errorlevel
此方法适用于要存储的(返回)值适合32位整数的情况。
例如,计算目录中的文件数并存储在名为count的变量中:

(dir /b /a-d ^| find /v /c "?") | (set /p myVar=& cmd /c exit /b %myVar%)
set count=%errorlevel%

详细- Win CMD整数限制测试:
Win CMD算术限制:2147483647(32位整数)
堆栈溢出将在-2147483648处继续计数,并在达到2147483647后再次重置

REM See tests below:
cmd /c exit /b 2147483647
echo %errorlevel%
2147483647

cmd /c exit /b 2147483648
echo %errorlevel%
-2147483648

cmd /c exit /b 2147483649
echo %errorlevel%
-2147483647

可以修改上述方法以返回要在父进程中解码的编码字符串(在32位限制内)。
第三个例子,虽然用途有限(因为变量是在子进程中设置的,而不是父进程):

(dir /b /a-d ^| find /v /c "?") | (set /p myVar=& set myVar)

在本例中,myVar的值被设置为目录中的文件数
在Win 10 CMD上测试。

2admgd59

2admgd595#

要读取文件...

set /P Variable=<File.txt

写入文件

@echo %DataToWrite%>File.txt

注意;在〈〉字符前有空格会导致在变量的末尾添加一个空格,也是
要添加到一个文件,如日志程序,首先创建一个文件,其中包含一个回车键,称为e.txt

set /P Data=<log0.log
set /P Ekey=<e.txt
@echo %Data%%Ekey%%NewData%>log0.txt

日志将如下所示

Entry1
Entry2

等等
不管怎样,有几个有用的东西

bnlyeluc

bnlyeluc6#

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

批量文件中

如果你在一个.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")

命令行

如果你在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")

说明

上面两个答案之间的唯一区别是,在命令行中,您在变量中使用单个%。在批处理文件中,您必须在百分号(%%)上使用两个。
由于该命令包含冒号、引号和圆括号,因此需要在选项中包含USEBACKQ行,以便可以使用反引号指定要运行的命令,然后在其中包含各种有趣的字符。

mqkwyuun

mqkwyuun7#

一些笔记和一些技巧。
将result赋值给变量的“官方”方法是使用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"

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

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"

%%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"
)

要在同一个FOR块中使用赋值变量,还需要检查DELAYED EXPANSION

And some tricks

为了保存编写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%

宏的第一个参数是命令,第二个参数是我们要使用的变量的名称,两者之间用,(逗号)分隔。
如果我们想要一个类似的控制台宏,我们可以使用***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%

DOSKEY不接受双引号作为参数的覆盖,因此这对于更简单的场景也很有用。
FOR也可以很好地与pipes一起工作,pipes可以用于链接命令(尽管它不太适合分配变量)。

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

它也可以用宏来美化:

@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]%

对于临时文件方法的完整宏(没有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%##

对于带有另一个宏的/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%
t30tvxxf

t30tvxxf8#

cd %windir%\system32\inetsrv

@echo off

for /F "tokens=* USEBACKQ" %%x in (      
        `appcmd list apppool /text:name`
       ) do (
            echo|set /p=  "%%x - " /text:name & appcmd.exe list apppool "%%x" /text:processModel.identityType
       )

echo %date% & echo %time%

pause
7y4bm7vi

7y4bm7vi9#

在大多数情况下,创建一个以变量名命名的临时文件可能是可以接受的。(因为你可能使用有意义的变量名…)
这里,我的变量名是SSH_PAGEANT_AUTH_SOCK

dir /w "\\.\pipe\\"|find "pageant" > %temp%\SSH_PAGEANT_AUTH_SOCK && set /P SSH_PAGEANT_AUTH_SOCK=<%temp%\SSH_PAGEANT_AUTH_SOCK

相关问题