コマンドの結果をWindowsバッチスクリプトの変数として取得しようとしています(bashスクリプトで同等の機能を実現するために、bashでコマンドの結果を取得する方法を参照してください)。.batファイルで機能するソリューションが推奨されますが、他の一般的なWindowsスクリプトソリューションも歓迎します。
コマンドの結果をWindowsバッチスクリプトの変数として取得しようとしています(bashスクリプトで同等の機能を実現するために、bashでコマンドの結果を取得する方法を参照してください)。.batファイルで機能するソリューションが推奨されますが、他の一般的なWindowsスクリプトソリューションも歓迎します。
回答:
すべてのコマンド出力をキャプチャする必要がある場合は、次のようなバッチを使用できます。
@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に格納されます。
@ジョン:これの実用的な用途はありますか?PowerShellや、スクリプトタスクを簡単に実行できるその他のプログラミング言語(Python、Perl、PHP、Ruby)を見る必要があると思います
cmd
そこで実行できるようにします。...はい、これは音と同じくらいひどいです。Visual Studioを使用すると、ときどき泣きたくなります。@ Ajedi32 バッチスクリプトは過去の恐ろしい遺物であると言うつもりだったと思います。;)
謙虚ためのコマンドは、長年にわたって、いくつかの興味深い機能を蓄積してきました。
D:\> FOR /F "delims=" %i IN ('date /t') DO set today=%i
D:\> echo %today%
Sat 20/09/2008
"delims="
は、デフォルトのスペースとタブ区切り文字を上書きするため、dateコマンドの出力が一度に乱れることに注意してください。
複数行の出力をキャプチャする場合でも、基本的には1行にすることができます(変数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"
FOR /F "delims=" %%i IN ('date /t') DO set today=%%i
for
コマンドラインでコマンドを直接入力する場合は、単一のを使用します%
。バッチファイルで使用する場合は、を使用します%%
。
%
例えば、:for /f "delims=" %%i in ('date +%F_%H-%M-%S') do set now=%%i
date
使用されるコマンドがCygwinからのものである場合、コマンドは有効です。私はそれについて言及すべきだったのに同意します。
現在のディレクトリを取得するには、これを使用できます:
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
しかし、より強力な別のシェルに移動することを検討したり、このようなアプリケーションを作成したりすることをお勧めします。バッチファイルの可能性をかなり広げています。
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
」として使用できます。ただし、すべての出力ではなく、出力の最初の行のみを取得します
「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
コマンドの結果を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
[クレジット]:他のすべての回答、および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 / 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.
その場合、コマンドを使用してその結果を変数に格納することがわかった唯一の解決策は、デフォルトのディレクトリをコマンド自体の1つに(一時的に)設定することです。
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です。Webサイトf2ko.de(http://f2ko.de/en/cmd.php)で見つけました。
誰かが複雑なパスを介してアクセスできるそのようなコマンドのより良い解決策を持っているなら、私はそれを聞いてとても嬉しいでしょう。
ジル
CALL
。パスにスペースがある場合、FOR / Fは機能しません
CALL "%SOURCEDIR%\FOLDERBROWSE" ... "quoted parameters"
>は完全に機能します。
すべての出力を1つの変数でキャプチャできますが、実際の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%
2番目のバージョン、内容を行ごとに印刷する必要がある場合。これは、「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=!
)
)
コマンド出力で何ができるかを説明しているhttp://technet.microsoft.com/en-us/library/bb490982.aspxを参照してください。
git pull>0 set /P RESULTVAR=<0
編集:おそらく、ここでは改行の使用方法がわかりません...各コマンドはそれ自体の行にあります。