Как получить результат команды в переменной в окнах?
Я хочу получить результат команды в виде переменной в пакете Windows script (см. как получить результат команды в bash для эквивалентного сценария bash). Предпочтительным является решение, которое будет работать в файле .bat, но также приветствуются другие распространенные сценарии для Windows.
Ответы
Ответ 1
Если вам нужно записать весь вывод команды, вы можете использовать такую команду:
@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, разделенном "!".
@John: есть ли практическое применение для этого? Я думаю, вы должны смотреть PowerShell или любой другой язык программирования, способный легко выполнять задачи сценариев (Python, Perl, PHP, Ruby)
Ответ 2
Смиренная команда для накопила несколько интересных возможностей за эти годы:
D:\> FOR /F "delims=" %i IN ('date /t') DO set today=%i
D:\> echo %today%
Sat 20/09/2008
Обратите внимание, что "delims="
перезаписывает разделители по умолчанию и разделители табуляции, так что вывод команды даты сразу получает ворс.
Чтобы захватить многострочный вывод, он может по существу быть однострочным (используя переменную 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"
Ответ 3
Чтобы получить текущий каталог, вы можете использовать это:
CD > tmpFile
SET /p myvar= < tmpFile
DEL tmpFile
echo test: %myvar%
Он использует временный файл, хотя он не самый красивый, но он, безусловно, работает! "CD" помещает текущий каталог в "tmpFile", "SET" загружает содержимое tmpFile.
Вот решение для нескольких строк с "массивом":
@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
Но вы можете подумать о переходе на другую более мощную оболочку или создать приложение для этого материала. Это немного расширяет возможности пакетных файлов.
Ответ 4
вам нужно использовать команду SET
с параметром /P
и направлять на нее свой вывод.
Например, см. http://www.ss64.com/nt/set.html. Будет работать для CMD, не уверен в файлах .BAT
Из комментария к этому сообщению:
В этой ссылке есть команда "Set /P
_MyVar=<MyFilename.txt
", в которой говорится, что она установит _MyVar
в первую строку от MyFilename.txt
. Это должно быть используется как "myCmd > tmp.txt
" с "set
/P myVar=<tmp.txt
". Но это будет получить первую строку вывода, а не все выходные
Ответ 5
Пример для установки в переменной окружения "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
Ответ 6
Если вы ищете решение, представленное в Использование результата команды в качестве аргумента в 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
[Credits]: благодаря всем остальным ответам и некоторым копаниям на странице Windows XP.
Ответ 7
@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%"
Ответ 8
Просто используйте результат из команды FOR
. Например (внутри пакетного файла):
for /F "delims=" %%I in ('dir /b /a-d /od FILESA*') do (echo %%I)
Вы можете использовать %%I
как необходимое значение. Точно так же: %%I
.
И заранее %%I
не имеет пробелов или символов CR и может использоваться для сравнения!!
Ответ 9
Вы можете записать весь вывод в одну переменную, но линии будут разделены символом по вашему выбору (# в примере ниже), а не фактическим 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=!
)
)
Ответ 10
Я хотел бы добавить замечание к вышеуказанным решениям:
Все эти синтаксисы работают отлично, ЕСЛИ ВАША КОМАНДА НАХОДИТСЯ В ПУТЕ, ЕСЛИ КОМАНДЫ - это 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". Если это не ваше дело, вам нужно найти способ найти путь к вашей команде и изменить каталог по умолчанию на свой путь.
NB: для тех, кто задается вопросом, команда образца, используемая здесь (для выбора папки), - FOLDERBROWSE.EXE. Я нашел его на веб-сайте f2ko.de(http://f2ko.de/en/cmd.php).
Если у кого-то есть лучшее решение для таких команд, доступных через сложный путь, я буду очень рад услышать об этом.
жилль
Ответ 11
Обратитесь к этому http://technet.microsoft.com/en-us/library/bb490982.aspx, который объясняет, что вы можете сделать с выходом команды.