2008-09-20 6 views
92

Ich bin auf der Suche nach dem Ergebnis eines Befehls als eine Variable in einem Windows-Batch-Skript (siehe how to get the result of a command in bash für die Bash-Skript-Entsprechung). Eine Lösung, die in einer .bat-Datei funktioniert, wird bevorzugt, aber auch andere gängige Windows-Scripting-Lösungen sind willkommen.Wie bekomme ich das Ergebnis eines Befehls in einer Variablen in Windows?

+8

John, es ist lächerlich schwer, diese ** sehr ** nützliche Frage zu finden. Könnten Sie bitte eine alternative Formulierung wie * Wie ** die ** Ausgabe ** eines ** Programms ** in eine Variable in einer Windows-Stapeldatei aufnehmen? * –

+3

Google hat diese Seite auf Rang 3 angezeigt. –

+1

Mögliches Duplikat von [Windows-Batch weist die Ausgabe eines Programms einer Variablen zu] (http://stackoverflow.com/questions/2323292/windows-batch-assign-output-of-a-program-to-a-variable) –

Antwort

24

Wenn Sie alle Befehlsausgabe erfassen haben, können Sie eine Charge wie folgt verwenden: „“

@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 

Alle Ausgangsleitungen in VAR mit getrennt gespeichert werden.

@John: Gibt es einen praktischen Nutzen dafür? Ich denke, Sie sollten sich PowerShell oder jede andere Programmiersprache ansehen, die Skriptaufgaben leicht ausführen kann (Python, Perl, PHP, Ruby)

+0

verwenden Die Antwort der einzelnen Zeile löst den spezifischen Fall, den ich habe. Ich dachte nur, dass es eine mehrzeilige Option (oder eine einfachere Einzeilige Option) gibt. Ich denke, die Fähigkeiten von Fledermaus-Dateien sind einfach nicht so toll. Die Notwendigkeit dafür ist für Fledermausskripte, die Java apps einwickeln. Hauptsächlich Klassenwege erstellen. –

+0

Seien Sie sehr vorsichtig damit. GWT hat auch versucht, Batch-Dateien zum Starten von Java mit bestimmten Klassenpfaden zu verwenden, was schief ging, sobald Sie zu Verzeichnissen mit Nicht-ASCII-Zeichen kommen (in diesem Fall war es mein Zuhause :)). Sie haben das mit VBS neu geschrieben. – Joey

+17

* Gibt es einen praktischen Nutzen dafür? * Machst du Witze? Dies wird ständig in anderen Shells verwendet (alle GNU/Linux-Versionen) und es ist sehr nützlich. –

-1

Bitte beachten Sie diese http://technet.microsoft.com/en-us/library/bb490982.aspx, die erklärt, was Sie mit der Befehlsausgabe tun können.

+1

Dieser Artikel behandelt nur Umleitung und verwandte Themen. Es beantwortet nicht die Frage, wie man die Ausgabe eines Befehls nimmt und in eine Variable bringt. –

+3

Mit seiner Antwort habe ich folgendes herausgefunden: 'git pull> 0 set/P RESULTVAR = <0' edit: Ich denke, ich weiß nicht, wie man hier Zeilenumbrüche verwendet ... jeder Befehl ist eingeschaltet es ist eine eigene Linie. – RibeiroBreno

5

müssen Sie den SET Befehl mit Parameter /P verwenden und Ihre Ausgabe darauf richten. Zum Beispiel siehe http://www.ss64.com/nt/set.html. Wird für CMD arbeiten, nicht sicher .bat-Dateien

Von einem Kommentar zu diesem Beitrag:

Diese Verbindung den Befehl „Set /P _MyVar=<MyFilename.txt“ hat, die sagt, es _MyVar in die erste Zeile von MyFilename.txt gesetzt wird. Dies könnte als "myCmd > tmp.txt" mit "set /P myVar=<tmp.txt" verwendet werden. Aber es wird nur die erste Zeile der Ausgabe erhalten, nicht die gesamte Ausgabe

+1

Diese Verknüpfung hat den Befehl "Set/P _MyVar = tmp.txt" mit "set/P myVar =

+2

so viel besser als die Syntax des for-Befehls – JJS

3

Beispiel in dem „V“ Umgebungsvariable setzt die aktuellste Datei

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

in einer Batch-Datei, die Sie haben Doppel Präfix in der Schleifenvariable verwenden:

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

Ich habe diesen Ansatz schon einmal gesehen, aber es scheint wirklich hacky. Es hat auch das Problem, dass es nur die letzte Zeile der Ausgabe von dem Befehl in der Variablen erfasst. –

62

der bescheidene für Befehl hat einige interessante CA akkumulierte higkeiten im Laufe der Jahre:

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

Beachten Sie, dass "delims=" den Standardraum und Tab-Trennzeichen überschreiben, so dass die Ausgabe des Befehls date wird auf einmal verschlungen.

mehrzeiligen Ausgang Zur Erfassung, kann es immer noch im wesentlichen ein Ein-Liner (die variable lf als Trennzeichen in der resultierenden Variable):

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% 

einen verrohrt Ausdruck zu erfassen, verwenden ^|:

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

Wie bei @ PabloG's Antwort wird dies nur funktionieren, um die letzte Ausgabezeile des Befehls "date/t" in diesem Fall zu erhalten. –

+8

Ich fand deine Antwort nur dann, wenn ich doppelte Prozentzeichen verwendete, dh "FOR/F" delims = "%% i IN ('Datum/t') Setzte heute = %% i' – Rabarberski

+12

@Rabarberski: Wenn du tippst ein 'for' Befehl direkt in der Befehlszeile, verwenden Sie eine einzelne'% '. Wenn Sie es in einer Batchdatei verwenden, verwenden Sie '%%'. – indiv

20

Um das aktuelle Verzeichnis zu erhalten, können Sie diese verwenden:

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

Es benutzt jedoch eine Temp-Datei, also ist es nicht die schönste, aber es funktioniert sicherlich! 'CD' setzt das aktuelle Verzeichnis in 'tmpFile', 'SET' lädt den Inhalt von tmpFile.

Hier ist eine Lösung für mehrere Zeilen mit „Arrays“:

@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 

Aber Sie könnten zu einem anderen leistungsfähigeren Schale bewegen betrachten wollen oder eine Anwendung für dieses Zeug erstellen. Es dehnt die Möglichkeiten der Batch-Dateien ziemlich aus.

+0

Gibt es eine Variante, die mehrere Zeilen vom Befehl erfasst? –

+4

Um das aktuelle Verzeichnis zu erhalten, können Sie echo% CD% – Joe

1

Sie können alle Ausgaben in einer Variablen erfassen, aber die Zeilen werden durch ein Zeichen von Ihrem getrennt Auswahl (# im Beispiel unten) anstelle eines tatsächlichen 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% 

Zweite Version, wenn Sie den Inhalt Zeile für Zeile ausdrucken müssen. Dies wird von der Tatsache unterstützt, dass es keine doppelten Zeilen der Ausgabe von "dir/b" geben wird, so dass es im allgemeinen Fall nicht funktionieren kann.

@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=! 
    ) 
) 
2

Wenn Sie sich für die Lösung zur Verfügung gestellt in Using the result of a command as an argument in bash?

dann hier ist der Code suchen:

@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 
  • Dies ruft sich mit dem Ergebnis der CD Befehl, gleiche als pwd.
  • String-Extraktion auf Parameter wird den Dateinamen/Ordner zurückgeben.
  • den Inhalt dieses Ordners Erhalten und zum filename.txt

[Credits] anhängen: Vielen Dank an alle anderen Antworten und einige Graben auf der Windows XP commands Seite.

2
@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%" 
+0

Danke für das Posten einer Antwort! Während ein Code-Snippet die Frage beantworten kann, ist es immer noch großartig, Zusatzinformationen wie Erklärungen usw. hinzuzufügen. – j0k

2

Verwenden Sie einfach das Ergebnis aus dem FOR Befehl. Zum Beispiel (in einer Batch-Datei):

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

können Sie die %%I als Wert verwenden Sie wollen. Einfach so: %%I.

Und im Voraus die %%I hat keine Leerzeichen oder CR-Zeichen und kann für Vergleiche verwendet werden !!

0

Ich möchte eine Bemerkung zu den oben genannten Lösungen hinzuzufügen:

All diese Syntaxen sehr gut funktionieren, wenn Ihr COMMAND IM WEG oder wenn der Befehl ein cmdpath ohne Leer- oder Sonderzeichen gefunden wird.

Wenn Sie jedoch versuchen, einen ausführbaren Befehl in einem Ordner zu verwenden, dessen Pfad Sonderzeichen enthält, müssen Sie den Befehlspfad in doppelte Anführungszeichen setzen (") und die FOR/F-Syntax funktioniert nicht.

Beispiele:

$ 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. 

oder

$ 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. 

oder

`$ 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 diesem Fall fand die einzige Lösung, die ich einen Befehl zu verwenden, und sein Ergebnis speichert in einer Variable ist, um (voreingestellt) das Standardverzeichnis auf das des Befehls selbst zu setzen:

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% 

Das Ergebnis ist dann richtig:

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

Natürlich in dem obigen Beispiel, nehme ich an, dass meine Batch-Skript im selben Ordner wie die eines meiner ausführbaren Befehl befindet, so dass ich verwenden kann, die "% ~ d0% ~ p0" -Syntax. Wenn dies nicht der Fall ist, müssen Sie einen Weg finden, Ihren Befehlspfad zu finden und das Standardverzeichnis in seinen Pfad zu ändern.

Hinweis: Für diejenigen, die sich fragen, ist der hier verwendete Beispielbefehl (um einen Ordner auszuwählen) FOLDERBROWSE.EXE. Ich habe es auf der Website f2ko.de (http://f2ko.de/en/cmd.php) gefunden.

Wenn jemand eine bessere Lösung für diese Art von Befehlen hat, die über einen komplexen Pfad zugänglich sind, werde ich mich sehr freuen, davon zu hören.

Gilles

+0

Sie können Ihren Befehl mit 'CALL' voranstellen. [FOR/F funktioniert nicht, wenn der Pfad Leerzeichen enthält] (https://Stackoverflow.com/a/6478227/463115) – jeb

+0

@jeb: DANKE SO VIEL! Mein Code <'CALL"% SOURCEDIR% \ FOLDERBROWSE "..." zitierte Parameter "'> funktioniert perfekt. –

Verwandte Themen