如何在 Windows 中的变量中获取命令的结果?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/108439/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I get the result of a command in a variable in windows?
提问by John Meagher
I'm looking to get the result of a command as a variable in a Windows batch script (see how to get the result of a command in bashfor the bash scripting equivalent). A solution that will work in a .bat file is preferred, but other common windows scripting solutions are also welcome.
我希望将命令的结果作为 Windows 批处理脚本中的变量获取(请参阅如何在 bash 中获取与 bash 脚本等效的命令的结果)。首选适用于 .bat 文件的解决方案,但也欢迎其他常见的 Windows 脚本解决方案。
采纳答案by PabloG
If you have to capture all the command output you can use a batch like this:
如果您必须捕获所有命令输出,您可以使用这样的批处理:
@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
All output lines are stored in VAR separated with "!".
所有输出行都存储在以“!”分隔的 VAR 中。
@John: is there any practical use for this? I think you should watch PowerShell or any other programming language capable to perform scripting tasks easily (Python, Perl, PHP, Ruby)
@John:这有什么实际用途吗?我认为您应该观看 PowerShell 或任何其他能够轻松执行脚本任务的编程语言(Python、Perl、PHP、Ruby)
回答by tardate
The humble forcommand has accumulated some interesting capabilities over the years:
多年来,谦虚的命令积累了一些有趣的功能:
D:\> FOR /F "delims=" %i IN ('date /t') DO set today=%i
D:\> echo %today%
Sat 20/09/2008
Note that "delims="
overwrites the default space and tab delimiters so that the output of the date command gets gobbled all at once.
请注意,它会"delims="
覆盖默认的空格和制表符分隔符,以便 date 命令的输出一次全部被吞噬。
To capture multi-line output, it can still essentially be a one-liner (using the variable lf as the delimiter in the resulting variable):
要捕获多行输出,它本质上仍然可以是单行(使用变量 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%
To capture a piped expression, use ^|
:
要捕获管道表达式,请使用^|
:
FOR /F "delims=" %%i IN ('svn info . ^| findstr "Root:"') DO set "URL=%%i"
回答by Evil Activity
To get the current directory, you can use this:
要获取当前目录,您可以使用:
CD > tmpFile
SET /p myvar= < tmpFile
DEL tmpFile
echo test: %myvar%
It's using a temp-file though, so it's not the most pretty, but it certainly works! 'CD' puts the current directory in 'tmpFile', 'SET' loads the content of tmpFile.
虽然它使用的是临时文件,所以它不是最漂亮的,但它确实有效!'CD' 将当前目录放在 'tmpFile' 中,'SET' 加载 tmpFile 的内容。
Here is a solution for multiple lines with "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
But you might want to consider moving to another more powerful shell or create an application for this stuff. It's stretching the possibilities of the batch files quite a bit.
但是您可能需要考虑转移到另一个更强大的 shell 或为这些东西创建一个应用程序。它大大扩展了批处理文件的可能性。
回答by Ilya Kochetov
you need to use the SET
command with parameter /P
and direct your output to it.
For example see http://www.ss64.com/nt/set.html. Will work for CMD, not sure about .BAT files
您需要使用SET
带参数的命令/P
并将输出定向到它。例如参见http://www.ss64.com/nt/set.html。将适用于 CMD,不确定 .BAT 文件
From a comment to this post:
从评论到这篇文章:
That link has the command "
Set /P _MyVar=<MyFilename.txt
" which says it will set_MyVar
to the first line fromMyFilename.txt
. This could be used as "myCmd > tmp.txt
" with "set /P myVar=<tmp.txt
". But it will only get the first line of the output, not all the output
该链接具有命令“
Set /P _MyVar=<MyFilename.txt
”,表示它将设置_MyVar
为MyFilename.txt
. 这可以用作“myCmd > tmp.txt
”和“set /P myVar=<tmp.txt
”。但它只会得到输出的第一行,而不是所有的输出
回答by PabloG
Example to set in the "V" environment variable the most recent file
在“V”环境变量中设置最新文件的示例
FOR /F %I IN ('DIR *.* /O:D /B') DO SET V=%I
in a batch file you have to use double prefix in the loop variable:
在批处理文件中,您必须在循环变量中使用双前缀:
FOR /F %%I IN ('DIR *.* /O:D /B') DO SET V=%%I
回答by Raceableability
Just use the result from the FOR
command. For example (inside a batch file):
只需使用FOR
命令的结果。例如(在批处理文件中):
for /F "delims=" %%I in ('dir /b /a-d /od FILESA*') do (echo %%I)
You can use the %%I
as the value you want. Just like this: %%I
.
您可以将%%I
用作您想要的值。就像这样:%%I
。
And in advance the %%I
does not have any spaces or CR characters and can be used for comparisons!!
并且预先%%I
没有任何空格或CR字符,可以用于比较!!
回答by Gilles Maisonneuve
I would like to add a remark to the above solutions:
我想对上述解决方案添加一句话:
All these syntaxes work perfectly well IF YOUR COMMAND IS FOUND WITHIN THE PATH or IF THE COMMAND IS A cmdpath WITHOUT SPACES OR SPECIAL CHARACTERS.
如果您的命令在路径内找到,或者如果命令是没有空格或特殊字符的 cmdpath,所有这些语法都可以很好地工作。
But if you try to use an executable command located in a folder which path contains special characters then you would need to enclose your command path into double quotes (") and then the FOR /F syntax does not work.
但是,如果您尝试使用位于路径包含特殊字符的文件夹中的可执行命令,则需要将命令路径括在双引号 (") 中,然后 FOR /F 语法不起作用。
Examples:
例子:
$ 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.
or
或者
$ 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.
or
或者
`$ 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.
In that case, the only solution I found to use a command and store its result in a variable is to set (temporarily) the default directory to the one of command itself :
在这种情况下,我发现使用命令并将其结果存储在变量中的唯一解决方案是(临时)将默认目录设置为命令本身之一:
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%
The result is then correct:
结果是正确的:
My selected folder: F:\GLW7\Distrib\System\OS install, recovery, VM\
Press any key to continue . . .
Of course in the above example, I assume that my batch script is located in the same folder as the one of my executable command so that I can use the "%~d0%~p0" syntax. If this is not your case, then you have to find a way to locate your command path and change the default directory to its path.
当然,在上面的例子中,我假设我的批处理脚本与我的可执行命令位于同一文件夹中,以便我可以使用“%~d0%~p0”语法。如果这不是您的情况,那么您必须找到一种方法来定位您的命令路径并将默认目录更改为其路径。
NB: For those who wonder, the sample command used here (to select a folder) is FOLDERBROWSE.EXE. I found it on the web site f2ko.de (http://f2ko.de/en/cmd.php).
注意:对于那些想知道的人,此处使用的示例命令(选择文件夹)是 FOLDERBROWSE.EXE。我在网站 f2ko.de ( http://f2ko.de/en/cmd.php)上找到了它。
If anyone has a better solution for that kind of commands accessible through a complex path, I will be very glad to hear of it.
如果有人对通过复杂路径访问的那种命令有更好的解决方案,我会很高兴听到它。
Gilles
吉尔斯
回答by Gustavo Carreno
If you're looking for the solution provided in Using the result of a command as an argument in bash?
如果您正在寻找使用命令的结果作为 bash 中的参数中提供的解决方案?
then here is the code:
然后这里是代码:
@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
- This will call itself with the result of the CD command, same as pwd.
- String extraction on parameters will return the filename/folder.
- Get the contents of this folder and append to the filename.txt
- 这将使用 CD 命令的结果调用自身,与 pwd 相同。
- 参数的字符串提取将返回文件名/文件夹。
- 获取此文件夹的内容并附加到 filename.txt
[Credits]: Thanks to all the other answers and some digging on the Windows XP commandspage.
[积分]:感谢所有其他答案以及对Windows XP 命令页面的一些挖掘。
回答by Hike
@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%"
回答by Adam Mitz
You can capture all output in one variable, but the lines will be separated by a character of your choice (# in the example below) instead of an actual CR-LF.
您可以在一个变量中捕获所有输出,但各行将由您选择的字符(在下面的示例中为 #)而不是实际的 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%
Second version, if you need to print the contents out line-by-line. This takes advanted of the fact that there won't be duplicate lines of output from "dir /b", so it may not work in the general case.
第二个版本,如果您需要逐行打印内容。这利用了这样一个事实,即“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=!
)
)