如何在窗口中的变量中获得命令的结果?

我希望在 Windows 批处理脚本中以变量的形式获得命令的结果(有关 bash 脚本的等效内容,请参阅 如何在 bash 中获得命令的结果)。中工作的解决方案。Bat 文件是首选,但也欢迎其他常见的 Windows 脚本解决方案。

314989 次浏览

请参考这个 http://technet.microsoft.com/en-us/library/bb490982.aspx,它解释了如何使用命令输出。

您需要使用带有参数 /PSET命令并将输出指向它。 例如,参见 http://www.ss64.com/nt/set.html.Will 为 CMD 工作,不确定是否适用于.BAT 文件

来自对这篇文章的评论:

该链接具有“ < code > Set/P”命令 _ MyVar = < MyFilename.txt ”,它表示将把 _MyVar设置为第一行 来自 MyFilename.txt这可能是 用作“ myCmd > tmp.txt”和“ < code > set” /P myVar = < tmp.txt ” 获取输出的第一行,而不是 所有的输出

在“ v”环境变量中设置最新文件的示例

FOR /F %I IN ('DIR *.* /O:D /B') DO SET V=%I

在批处理文件中,你必须在循环变量中使用双前缀:

FOR /F %%I IN ('DIR *.* /O:D /B') DO SET V=%%I

不起眼的 为了命令多年来积累了一些有趣的功能:

D:\> FOR /F "delims=" %i IN ('date /t') DO set today=%i
D:\> echo %today%
Sat 20/09/2008

注意,"delims="覆盖了默认的空格和制表符分隔符,这样 date 命令的输出可以一次性全部获取。

为了捕获多行输出,它仍然可以是一行程序(使用变量 lf 作为结果变量中的分隔符) :

REM NB:in a batch file, need to use %%i not %i
setlocal EnableDelayedExpansion
SET lf=-
FOR /F "delims=" %%i IN ('dir \ /b') DO if ("!out!"=="") (set out=%%i) else (set out=!out!%lf%%%i)
ECHO %out%

要捕获管道表达式,请使用 ^|:

FOR /F "delims=" %%i IN ('svn info . ^| findstr "Root:"') DO set "URL=%%i"

要获得工作目录,你可以使用以下方法:

CD > tmpFile
SET /p myvar= < tmpFile
DEL tmpFile
echo test: %myvar%

虽然它使用的是临时文件,所以它不是最漂亮的,但它肯定工作!“ CD”将工作目录放在“ tmpFile”中,“ SET”加载 tmpFile 的内容。

下面是一个用“ array’s”表示多行的解决方案:

@echo off


rem ---------
rem Obtain line numbers from the file
rem ---------


rem This is the file that is being read: You can replace this with %1 for dynamic behaviour or replace it with some command like the first example i gave with the 'CD' command.
set _readfile=test.txt


for /f "usebackq tokens=2 delims=:" %%a in (`find /c /v "" %_readfile%`) do set _max=%%a
set /a _max+=1
set _i=0
set _filename=temp.dat


rem ---------
rem Make the list
rem ---------


:makeList
find /n /v "" %_readfile% >%_filename%


rem ---------
rem Read the list
rem ---------


:readList
if %_i%==%_max% goto printList


rem ---------
rem Read the lines into the array
rem ---------
for /f "usebackq delims=] tokens=2" %%a in (`findstr /r "\[%_i%]" %_filename%`) do set _data%_i%=%%a
set /a _i+=1
goto readList


:printList
del %_filename%
set _i=1
:printMore
if %_i%==%_max% goto finished
set _data%_i%
set /a _i+=1
goto printMore


:finished

但是您可能需要考虑迁移到另一个更强大的 shell,或者为此创建一个应用程序。这大大增加了批处理文件的可能性。

如果您必须捕获所有的命令输出,您可以使用如下批处理:

@ECHO OFF
IF NOT "%1"=="" GOTO ADDV
SET VAR=
FOR /F %%I IN ('DIR *.TXT /B /O:D') DO CALL %0 %%I
SET VAR
GOTO END


:ADDV
SET VAR=%VAR%!%1


:END

所有输出行都存储在以“ !”分隔的 VAR 中。

但是,如果只需要单行控制台输出,请尝试:

@ECHO off
@SET MY_VAR=
FOR /F %%I IN ('npm prefix') DO @SET "MY_VAR=%%I"


@REM Do something with MY_VAR variable...

@ John: 这有什么实际用途吗?我认为您应该看看 PowerShell 或其他能够轻松执行脚本任务的编程语言(Python、 Perl、 PHP、 Ruby)

您可以在一个变量中捕获所有输出,但是这些行将由您选择的字符(下面示例中的 #)分隔,而不是实际的 CR-LF。

@echo off
setlocal EnableDelayedExpansion
for /f "delims=" %%i in ('dir /b') do (
if "!DIR!"=="" (set DIR=%%i) else (set DIR=!DIR!#%%i)
)
echo directory contains:
echo %DIR%

第二个版本,如果需要逐行打印内容。这考虑到了“ dir/b”不会有重复的输出行这一事实,因此在一般情况下可能无法工作。

@echo off
setlocal EnableDelayedExpansion
set count=0
for /f "delims=" %%i in ('dir /b') do (
if "!DIR!"=="" (set DIR=%%i) else (set DIR=!DIR!#%%i)
set /a count = !count! + 1
)


echo directory contains:
echo %DIR%


for /l %%c in (1,1,%count%) do (
for /f "delims=#" %%i in ("!DIR!") do (
echo %%i
set DIR=!DIR:%%i=!
)
)

如果您正在寻找 在 bash 中使用命令的结果作为参数?中提供的解决方案

这就是密码:

@echo off
if not "%1"=="" goto get_basename_pwd
for /f "delims=X" %%i in ('cd') do call %0 %%i
for /f "delims=X" %%i in ('dir /o:d /b') do echo %%i>>%filename%.txt
goto end


:get_basename_pwd
set filename=%~n1


:end
  • 这将使用 CD 命令的结果调用它自己,与 pwd 相同。
  • 对参数的字符串提取将返回文件名/文件夹。
  • 获取此文件夹的内容并附加到 filename.txt

感谢所有其他的答案和对 Windows XP 命令页面的一些挖掘。

@echo off


ver | find "6.1." > nul
if %ERRORLEVEL% == 0 (
echo Win7
for /f "delims=" %%a in ('DIR "C:\Program Files\Microsoft Office\*Outlook.EXE" /B /P /S') do call set findoutlook=%%a
%findoutlook%
)


ver | find "5.1." > nul
if %ERRORLEVEL% == 0 (
echo WinXP
for /f "delims=" %%a in ('DIR "C:\Program Files\Microsoft Office\*Outlook.EXE" /B /P /S') do call set findoutlook=%%a
%findoutlook%
)
echo Outlook dir:  %findoutlook%
"%findoutlook%"

只需使用 FOR命令的结果。例如(在批处理文件中) :

for /F "delims=" %%I in ('dir /b /a-d /od FILESA*') do (echo %%I)

您可以使用 %%I作为您想要的值。

而且事先 %%I没有任何空格或 CR 字符,可以用来进行比较! !

对于上述解决办法,我想补充一点:

如果您的命令位于路径中,或者命令是一个没有空格或特殊字符的 cmdpath,那么所有这些语法都可以很好地工作。

但是,如果您尝试使用位于路径包含特殊字符的文件夹中的可执行命令,那么您需要将命令路径放入双引号(“)中,然后 FOR/F 语法就不起作用了。

例子:

$ for /f "tokens=* USEBACKQ" %f in (
`""F:\GLW7\Distrib\System\Shells and scripting\f2ko.de\folderbrowse.exe"" Hello '"F:\GLW7\Distrib\System\Shells and scripting"'`
) do echo %f
The filename, directory name, or volume label syntax is incorrect.

或者

$ for /f "tokens=* USEBACKQ" %f in (
`"F:\GLW7\Distrib\System\Shells and scripting\f2ko.de\folderbrowse.exe" "Hello World" "F:\GLW7\Distrib\System\Shells and scripting"`
) do echo %f
'F:\GLW7\Distrib\System\Shells' is not recognized as an internal or external command, operable program or batch file.

或者

`$ for /f "tokens=* USEBACKQ" %f in (
`""F:\GLW7\Distrib\System\Shells and scripting\f2ko.de\folderbrowse.exe"" "Hello World" "F:\GLW7\Distrib\System\Shells and scripting"`
) do echo %f
'"F:\GLW7\Distrib\System\Shells and scripting\f2ko.de\folderbrowse.exe"" "Hello' is not recognized as an internal or external command, operable program or batch file.

在这种情况下,我发现使用命令并将其结果存储在变量中的唯一解决方案是将(临时)默认目录设置为命令本身的目录:

pushd "%~d0%~p0"
FOR /F "tokens=* USEBACKQ" %%F IN (
`FOLDERBROWSE "Hello world!" "F:\GLW7\Distrib\System\Layouts (print,display...)"`
) DO (SET MyFolder=%%F)
popd
echo My selected folder: %MyFolder%

结果是正确的:

My selected folder: F:\GLW7\Distrib\System\OS install, recovery, VM\
Press any key to continue . . .

当然,在上面的示例中,我假设我的批处理脚本与我的可执行命令位于同一个文件夹中,因此我可以使用“% ~ d0% ~ p0”语法。如果不是这种情况,那么您必须找到一种方法来定位命令路径,并将默认目录更改为其路径。

注意: 对于那些想知道的人,这里使用的示例命令(选择一个文件夹)是 FOLDERBROWSE.EXE。我在 f2ko.de (http://f2ko.de/en/cmd.php)网站上找到的。

如果有人有更好的解决方案,可以通过复杂的路径访问这类命令,我将非常高兴地听到它。

吉尔斯

@echo off
setlocal EnableDelayedExpansion
FOR /F "tokens=1 delims= " %%i IN ('echo hola') DO (
set TXT=%%i
)
echo 'TXT: %TXT%'

结果是‘ TXT: hola’

你应该使用 for命令,下面是一个例子:

@echo off
rem Commands go here
exit /b
:output
for /f "tokens=* useback" %%a in (`%~1`) do set "output=%%a"

你可以使用 call :output "Command goes here",然后输出将在 %output%变量。

注意: 如果您有一个多行命令输出,这个工具将 set作为多行命令最后一行的输出。