Jak ustawić dane wyjściowe poleceń jako zmienne w pliku wsadowym


242

Czy można ustawić wyjście instrukcji wsadowej pliku wsadowego na zmienną, na przykład:

findstr testing > %VARIABLE%

echo %VARIABLE%

2
możliwy duplikat
Batchowego ekwipunku



kolejny duplikat dla zabawy:
Pakiet

Odpowiedzi:


275
FOR /F "tokens=* USEBACKQ" %%F IN (`command`) DO (
SET var=%%F
)
ECHO %var%

Zawsze używam USEBACKQ, więc jeśli masz ciąg do wstawienia lub długą nazwę pliku, możesz użyć podwójnych cudzysłowów bez spieprzenia polecenia.

Teraz, jeśli twój wynik będzie zawierał wiele wierszy, możesz to zrobić

SETLOCAL ENABLEDELAYEDEXPANSION
SET count=1
FOR /F "tokens=* USEBACKQ" %%F IN (`command`) DO (
  SET var!count!=%%F
  SET /a count=!count!+1
)
ECHO %var1%
ECHO %var2%
ECHO %var3%
ENDLOCAL

3
Pracowałem dla mnie w systemie Win7, dzięki! (i tak, to 7 lat przydatności) PS Nie zapomnij rozwinąć% do %% w poleceniach!
Dmitry Ilukhin

Działa to świetnie ... chyba że dane wyjściowe zawierają wykrzykniki (!), Ponieważ podczas interpretacji będą one interpretowane jako znaki kontrolneENABLEDELAYEDEXPANSION
JonathanDavidArndt

Działa dobrze, z wyjątkiem sytuacji, gdy musisz użyć, |w którym to przypadku nie działa.
Matt Vukomanovic

6
@MattVukomanovic działa dla mnie za pomocą ^|zamiast |, jak opisano tutaj
AST

Czy w ogóle możliwe jest przechwycenie kodu wyjścia command? Jestem pewien, że zwraca niezerowy kod, ale %ERRORLEVEL%zawsze zawiera 0, bez względu na to, gdzie próbuję go użyć (nawet wewnątrz dobloku). Więc chyba część tego forkonstruktu go nadpisuje. BTW To niewiarygodne, jak szalenie wyglądający kod jest potrzebny do czegoś tak podstawowego.
David Ferenczy Rogožan

69

Znalazłem ten wątek na tamtej stronie Interweb. Sprowadza się do:

@echo off 
setlocal enableextensions 
for /f "tokens=*" %%a in ( 
'VER' 
) do ( 
set myvar=%%a 
) 
echo/%%myvar%%=%myvar% 
pause 
endlocal 

Możesz także przekierować dane wyjściowe polecenia do pliku tymczasowego, a następnie umieścić zawartość tego pliku tymczasowego w zmiennej, tak jak to ma miejsce. Jednak nie działa z wejściem wieloliniowym.

cmd > tmpFile 
set /p myvar= < tmpFile 
del tmpFile 

Podziękowania dla wątku na sprzęcie Toma.


3
Jedyną wadą podejścia do dołu (co jest preferowane pod każdym innym względem) jest to, że nie działa z wyjściem wieloliniowym.
dgo

W przypadku wersji VER poszedłbym inną drogą: dla tokenów / f = 2 delims = [,] "%% a in ('ver') ustaw wersję %% echo% version%
Hardoman

1
jesteś drugim wynikiem dla Likeuchashereby - imagebin.ca/v/4NPSlQFgifce
Shmuel Kamensky

Drugi przykład bardzo pomógł mi w pisaniu pliku wsadowego w celu sprawdzenia wersji pliku chromedriver.exe w porównaniu z plikiem tekstowym zawierającym numer wersji. Jestem starym dinozaurem z DOS i nie byłem świadomy przełączeń na polecenie set. Inne rzeczy były dla mnie przesadą.
Bill Hileman,

47

w jednym wierszu:

FOR /F "tokens=*" %g IN ('*your command*') do (SET VAR=%g)

wynik polecenia zostanie ustawiony w% g, a następnie w VAR.

Więcej informacji: https://ss64.com/nt/for_cmd.html


19
Moja partia nie uruchomiła się z „% g”. Działało z „%% g”.
Santiago Villafuerte,

5
+ Santiago Villafuerte: tak, jeśli uruchamiasz z pliku wsadowego, ale jeśli chcesz sam uruchomić go z wiersza poleceń (na przykład: przetestować przed umieszczeniem go w pliku wsadowym), użyj jednego%.
Brent Rittenhouse

19

Aby odczytać plik ...

set /P Variable=<File.txt

Aby zapisać plik

@echo %DataToWrite%>File.txt

Uwaga; spacje przed znakiem <> powodują także dodanie spacji na końcu zmiennej

Aby dodać do pliku, podobnie jak program rejestrujący, najpierw utwórz plik z jednym klawiszem Enter o nazwie e.txt

set /P Data=<log0.log
set /P Ekey=<e.txt
@echo %Data%%Ekey%%NewData%>log0.txt

Twój dziennik będzie wyglądał tak

Entry1
Entry2 

i tak dalej

W każdym razie kilka przydatnych rzeczy


Dziękuję za Twoją odpowiedź. BTW "set / P Variable = <File.txt" czyta tylko pierwszą linię pliku
Deepscorn

19

Wszystkie te odpowiedzi były tak bliskie odpowiedzi, której potrzebowałem. To jest próba rozwinięcia się na nich.

W pliku wsadowym

Jeśli uruchamiasz się z .batpliku i potrzebujesz jednej linii, która pozwala wyeksportować skomplikowane polecenie, np. jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.jsonDo zmiennej o nazwie, AWS_ACCESS_KEYto chcesz:

FOR /F "tokens=* USEBACKQ" %%g IN (`jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json`) do (SET "AWS_ACCESS_KEY=%%g")

W wierszu poleceń

Jeśli pojawi się C:\monit, potrzebujesz pojedynczej linii, która pozwala na uruchomienie skomplikowanego polecenia, takiego jak jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.jsonzmienna o nazwie, AWS_ACCESS_KEYto chcesz:

FOR /F "tokens=* USEBACKQ" %g IN (`jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json`) do (SET "AWS_ACCESS_KEY=%g")

Wyjaśnienie

Jedyna różnica między dwiema powyższymi odpowiedziami polega na tym, że w wierszu poleceń używasz jednego% w zmiennej. W pliku wsadowym należy podwoić znaki procentowe (%%).

Ponieważ polecenie zawiera dwukropki, cudzysłowy i nawiasy, należy włączyć USEBACKQwiersz w opcjach, aby można było użyć cudzysłowów w celu określenia polecenia do uruchomienia, a następnie wszelkiego rodzaju zabawnych znaków w nim zawartych.


13

Jeśli nie chcesz wyprowadzać danych do pliku tymczasowego, a następnie wczytywać do zmiennej, ten kod przechowuje wynik polecenia bezpośrednio w zmiennej:

FOR /F %i IN ('findstr testing') DO set VARIABLE=%i
echo %VARIABLE%

Jeśli chcesz zawrzeć szukany ciąg w podwójnych cudzysłowach:

FOR /F %i IN ('findstr "testing"') DO set VARIABLE=%i

Jeśli chcesz zapisać ten kod w pliku wsadowym, dodaj dodatkowy symbol%:

FOR /F %%i IN ('findstr "testing"') DO set VARIABLE=%%i

Przydatny przykład zliczania liczby plików w katalogu i przechowywania w zmiennej: (ilustruje potokowanie)

FOR /F %i IN ('dir /b /a-d "%cd%" ^| find /v /c "?"') DO set /a count=%i

Zauważ użycie pojedynczych cudzysłowów zamiast cudzysłowach "lub akcentem` w nawiasach poleceń. To jest czystsze alternatywa delims, tokenslub usebackqw forpętli.

Testowany na Win 10 CMD.


1
cd %windir%\system32\inetsrv

@echo off

for /F "tokens=* USEBACKQ" %%x in (      
        `appcmd list apppool /text:name`
       ) do (
            echo|set /p=  "%%x - " /text:name & appcmd.exe list apppool "%%x" /text:processModel.identityType
       )

echo %date% & echo %time%

pause

Nie rozumiem, jak to rozwiązuje pytanie. appcmdnie jest standardowym programem i nie widzę, gdzie przypisujesz wyjście programu do zmiennej. W końcu potrzebujesz więcej wyjaśnień
jeb

-3

Przetestowałem to w ten sposób i zadziałało:

SET /P Var= | Cmd

Przesyłając polecenie do zmiennej, monit wstawi wynik polecenia „ Cmd” do zmiennej „ Var”.

Aktualizacja:

To nie działa, mój zły, skrypt, który napisałem był następujący:

SET /P Var= | dir /b *.txt
echo %Var%

Właściwie pokazywał, powiedzmy „test.txt ”, ale w rzeczywistości pokazywał wynik dir /b *.txtpolecenia „ ”, a nie echo %var%. Byłem zdezorientowany, ponieważ oba wyjścia były takie same.


3
Jeśli zamierzałeś pipe the command into a variable promptto zrobić, powinieneś to napisać, dir /b *.txt | SET /P Var=aby uzyskać prawidłowy kierunek rury. PS: To też nie działa w ten sposób!
Jesse Chisholm

-18

Mam nadzieję, że to pomoże

set a=%username%
echo %a%    
set a="hello"
echo %a%

5
Nie, to nie odpowiada na pytanie. Pytanie ma zamiar przenieść dane wyjściowe polecenia do zmiennej
jeb

Prostym sposobem jest zapisanie do pliku i odczytanie go z tego pliku. findstr "test" test.txt> testoutput.txt zestaw /pa=<testoutput.txt echo% a%
Ben2014
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.