Uitgang van een opdracht instellen als een variabele (met pijpen)

Kunt u de uitvoer van een opdracht naar een variabele met buizen omleiden?

Ik heb niet veel geprobeerd, want ik heb niets kunnen bedenken om te proberen, maar ik heb een methode (met twee variaties) geprobeerd …

Bijvoorbeeld:

echo Hello|set text=

werkte niet, ook niet:

echo Hello|set text=

Ik weet dat je het vrij gemakkelijk kunt doen met de FORopdracht, maar ik denk dat het er “mooier” met een pijp uit zou zien.

En als u zich afvraagt, heb ik geen specifieke reden waarom ik dit vraag dan ben ik nieuwsgierig en ik kan het antwoord niet vinden.


Antwoord 1, Autoriteit 100%

Uw weg kan niet om twee redenen werken.

U moet set /p text=gebruiken voor het instellen van de variabele met Gebruikersinvoer .
Het andere probleem is de pijp.
Een pijp start twee asynchrone cmd.exe-instanties en na het afronden van de baan zijn beide instanties gesloten.

Dat is de oorzaak waarom het lijkt dat de variabelen niet zijn ingesteld, maar een klein voorbeeld laat zien dat ze zijn ingesteld, maar het resultaat is later verloren.

set myVar=origin
echo Hello | (set /p myVar= & set myVar)
set myVar

Uitgangen

Hello
origin

alternatieven: U kunt de voor lus gebruiken om waarden in variabelen of ook temp-bestanden te krijgen.

for /f "delims=" %%A in ('echo hello') do set "var=%%A"
echo %var%

of

>output.tmp echo Hello
>>output.tmp echo world
<output.tmp (
  set /p line1=
  set /p line2=
)
echo %line1%
echo %line2%

alternatief met een macro:

U kunt een batchmacro gebruiken, dit is een beetje zoals het bash-equivalent

@echo off
REM *** Get version string 
%$set% versionString="ver"
echo The version is %versionString[0]%
REM *** Get all drive letters
`%$set% driveLetters="wmic logicaldisk get name /value | findstr "Name""
call :ShowVariable driveLetters

De definitie van de macro is te vinden op
SO: Wijs de uitvoer van een programma toe aan een variabele met behulp van een MS-batchbestand


Antwoord 2, Autoriteit 28%

Het gebrek aan een Linux-achtige backtick / backquote Faciliteit is een belangrijke ergernis van de pre-Powershell-wereld. Het gebruik van Backquotes via For-Loops is helemaal niet gezellig. Dus we hebben een beetje nodig van setvar myvar cmd-linecommando.

In mijn %path%Ik heb een dir met een aantal bakken en batches om te gaan met die win-tekortkomingen.

Eén batch die ik schreef, is:

:: setvar varname cmd
:: Set VARNAME to the output of CMD
:: Triple escape pipes, eg:
:: setvar x  dir c:\ ^^^| sort 
:: -----------------------------
@echo off
SETLOCAL
:: Get command from argument 
for /F "tokens=1,*" %%a in ("%*") do set cmd=%%b
:: Get output and set var
for /F "usebackq delims=" %%a in (`%cmd%`) do (
     ENDLOCAL
     set %1=%%a
)
:: Show results 
SETLOCAL EnableDelayedExpansion
echo %1=!%1! 

Dus in uw geval, zou u typen:

> setvar text echo Hello
text=Hello 

Het script informeert u over de resultaten, wat betekent dat u:

> echo text var is now %text%
text var is now Hello 

U kunt een opdracht gebruiken:

> setvar text FIND "Jones" names.txt

Wat als de opdracht die u wilt pijpen naar een aantal variabele, zelf een pijp bevat?
Triple Escape It, ^^^|:

> setvar text dir c:\ ^^^| find "Win"

Antwoord 3, Autoriteit 9%

Dit gebruikt geen pijpen, maar vereist een enkele tempfile
Ik heb dit gebruikt om vereenvoudigde tijdstempels in een Lowtech Daily Maintenance Batfile

We hebben onze systeemtijd al kort geformatteerd naar HHMM, (wat 2245 is voor 10:45 uur)
I Directe output van MAINT-Routines naar LogFiles met een $ Date% @% Time% tijdstempel;
. . . Maar% Time% is een lange lelijke string (excl. 224513.56, voor down to the honderdsten van een sec)

OVERZICHT OPLOSSING:
1. Gebruik omleiding (“>”) om elke keer het commando “TIME /T” te sturen om een ​​tijdelijk bestand in de %TEMP% DIRECTORY
te OVERSCHRIJVEN
2. Gebruik dan dat tijdelijke bestand als invoer om een ​​nieuwe variabele in te stellen (ik noemde het NU)
3. Vervang

echo $DATE%@%TIME% blah-blah-blah >> %logfile%

      met

echo $DATE%@%NOW% bla-bla-bla >> %logfile%

====VERSCHIL IN UITVOER:
VOOR:

SUCCESVOLLE TIMESYNCH [email protected]

NA:

SUCCESVOLLE TIMESYNCH 29Dec14@2252

WERKELIJKE CODE:

TIJD /T > %TEMP%\DailyTemp.txt
SET /p NOW=<%TEMP%\DailyTemp.txt
echo $DATE%@%NOW% bla-bla-bla >> %logfile%

AFTERMATH:
Het enige dat daarna overblijft is het bijgevoegde logbestand en het constant overschreven tempfile. En als het Tempfile ooit wordt verwijderd, wordt het indien nodig opnieuw gemaakt.


Antwoord 4, autoriteit 6%

Ik sta een beetje versteld van het gebrek aan wat ik beschouw als het beste antwoord op deze vraag waar dan ook op internet. Ik heb jarenlang geworsteld om het antwoord te vinden. Veel online antwoorden komen in de buurt, maar geen enkele beantwoordt het echt. Het echte antwoord is

(cmd & echo.) >2 & (set /p =)<2

De ‘geheime saus’ is het ‘goed bewaakte felbegeerde geheim’ dat ‘echo’. stuurt een CR/LF (ENTER/nieuwe regel/0x0D0A). Anders, wat ik hier doe, is de uitvoer van de eerste opdracht omleiden naar de standaardfoutstroom. Vervolgens stuur ik de standaardfoutstroom om naar de standaard invoerstroom voor de opdracht “set /p =”.

Voorbeeld:

(echo foo & echo.) >2 & (set /p bar=)<2


Antwoord 5, autoriteit 4%

In een batchbestand maak ik meestal een bestand aan in de tijdelijke map en
voeg uitvoer van een programma toe, dan noem ik het
met een variabelenaam om die variabele in te stellen.
Zoals dit:

:: Create a set_var.cmd file containing: set %1=
set /p="set %%1="<nul>"%temp%\set_var.cmd"
:: Append output from a command
ipconfig | find "IPv4" >> "%temp%\set_var.cmd"
call "%temp%\set_var.cmd" IPAddress
echo %IPAddress%

Antwoord 6

U kunt de uitvoer instellen op een tijdelijk bestand en de gegevens uit het bestand lezen, daarna kunt u het tijdelijke bestand verwijderen.

echo %date%>temp.txt
set /p myVarDate= < temp.txt
echo Date is %myVarDate%
del temp.txt

In deze variabele bevat myVarDatede uitvoer van het commando.

Other episodes