是否可以将批处理文件的语句输出设置为一个变量,例如:
findstr testing > %VARIABLE%
echo %VARIABLE%
是否可以将批处理文件的语句输出设置为一个变量,例如:
findstr testing > %VARIABLE%
echo %VARIABLE%
当前回答
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
其他回答
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
读取文件…
set /P Variable=<File.txt
写文件
@echo %DataToWrite%>File.txt
请注意;<>字符前有空格也会导致在变量末尾添加空格
要添加到文件中,就像日志程序一样, 首先创建一个文件,其中只有一个enter键,名为e.txt
set /P Data=<log0.log
set /P Ekey=<e.txt
@echo %Data%%Ekey%%NewData%>log0.txt
你的日志是这样的
Entry1
Entry2
等等
总之,有一些有用的东西
一些笔记和一些技巧。
将结果分配给变量的“正式”方式是使用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
还有一些技巧
为了避免为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也可以很好地用于连接命令的管道(尽管它不太适合分配变量)。
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%
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
这些答案都非常接近我需要的答案。这是一种扩展它们的尝试。
在批处理文件中
如果您在.bat文件中运行,并且需要一行允许您导出像jq -r ". credentials这样复杂的命令。c: \ temp \ mfa-getCreds AccessKeyId”。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这样复杂的命令。c: \ temp \ mfa-getCreds AccessKeyId”。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行,以便使用反引号指定要运行的命令,然后在其中使用各种有趣的字符。