MS बैच फ़ाइल का उपयोग करके प्रोग्राम के आउटपुट को वेरिएबल में असाइन करें


290

मुझे MS बैच फ़ाइल का उपयोग करके प्रोग्राम के आउटपुट को एक वैरिएबल में असाइन करना होगा।

इसलिए जीएनयू बैश शेल में मैं उपयोग करूंगा VAR=$(application arg0 arg1)। मुझे एक बैच फ़ाइल का उपयोग करके विंडोज में समान व्यवहार की आवश्यकता है।

कुछ इस तरह set VAR=application arg0 arg1

जवाबों:


433

एक तरीका है:

application arg0 arg1 > temp.txt
set /p VAR=<temp.txt

एक और है:

for /f %%i in ('application arg0 arg1') do set VAR=%%i

ध्यान दें कि पहले %में %%iसे बचने के लिए प्रयोग किया जाता है %इसके बाद और जब एक बैच फ़ाइल में बजाय कमांड लाइन पर उपरोक्त कोड का उपयोग कर की जरूरत है। कल्पना कीजिए, आपके test.batपास कुछ ऐसा है:

for /f %%i in ('c:\cygwin64\bin\date.exe +"%%Y%%m%%d%%H%%M%%S"') do set datetime=%%i
echo %datetime%

11
यह एक महान चाल है, मुझे आश्चर्य है कि यह एक पाइप के साथ काम क्यों नहीं करता है
बिल के

25
यह केवल आउटपुट के लिए काम करता है जो पाठ की एक एकल पंक्ति है (बाद की लाइनें पहली पंक्ति के विराम के बाद छोड़ी गई)।
GroovyCakes 21

20
@ माच्टा पाइप को इसके पहले ^ चिन्ह से बचना चाहिए, जो कि परेंस में अभिव्यक्ति के अंदर है। उदाहरण:for /f "tokens=3" %%i in ('route print ^| findstr "\<0.0.0.0\>"') do set "myVar=%%i"
इमानुएल डेल ग्रांडे

8
रिक्त स्थान के साथ लाइन के लिए काम न करें। उदाहरण के लिए: / f %% i में ('ver') सेट VAR = %% i। जैसा कि @Renat ने लिखा है, "टोकन = *" जोड़ना चाहिए
यूरा

2
@GroovyCakes आउटपुट में कई पंक्तियों के बारे में आपके प्रश्न का उत्तर इस प्रश्न के उत्तर में दिया गया है
icc97

67

इस पिछले उत्तर के अतिरिक्त , पाइपों का उपयोग स्टेटमेंट के अंदर किया जा सकता है, एक कैरेट प्रतीक द्वारा बच गए:

    for /f "tokens=*" %%i in ('tasklist ^| grep "explorer"') do set VAR=%%i

1
दो महत्वपूर्ण बिंदु: पाइप से बचने और पकड़ने के लिए टोकन का उपयोग करें।
क्रिस्टोफर ओजबेक

6
समतुल्य संस्करण जो सीएलआई पर काम करता है और आसान टिंकरिंग के लिए कॉपी-पेस्ट किया जा सकता है: for /f "tokens=*" %i in ('tasklist ^| findstr explorer') do @echo %iलेकिन सामान्य तौर पर, usebackqइसका उपयोग जटिल आदेशों को संभालने के लिए किया जाना चाहिए।
अमित नायडू

आउटपुट में रिक्त स्थान को संभालने के लिए टोकन की आवश्यकता थी।
मार्क इनग्राम

उद्धरण मेरे लिए के रूप में अच्छी तरह से काम करते हैं, इस तरह: for /f "tokens=*" %%i in ('"tasklist | grep explorer"') do set VAR=%%i। मेरे लिए आसान है अगर कमांड में ही कोई उद्धरण नहीं है।
पॉल

10

@OP, आप अपने प्रोग्राम के रिटर्न स्टेटस को कैप्चर करने के लिए लूप्स का उपयोग कर सकते हैं , अगर यह संख्याओं के अलावा कुछ और आउटपुट करता है


8

यह मानते हुए कि आपके एप्लिकेशन का आउटपुट एक संख्यात्मक रिटर्न कोड है, आप निम्न कार्य कर सकते हैं

application arg0 arg1
set VAR=%errorlevel%

5
दुर्भाग्य से, आउटपुट एक स्ट्रिंग है।
3

ठीक है। मैं इसे पोस्टीरिटी के लिए रखूंगा, लेकिन @ jdigital के लिंक पर एक नज़र डालूंगा, जो एक टेम्पर्ड फाइल में पाइपिंग आउटपुट के बारे में बात करता है।
akf

1
Stdout और stderr के लिए प्रोग्राम का आउटपुट पूर्णांक रिटर्न मान से अलग है। एक प्रोग्राम दोनों एक पूर्णांक मान को ऊपर के उदाहरण में वापस कर सकता है, जबकि कंसोल को एक स्ट्रिंग भेज सकता है (या किसी फ़ाइल या अन्य जगहों पर पुनर्निर्देशित)। वे परस्पर अनन्य नहीं हैं और दो अलग अवधारणाएं हैं।
डेविड रेक्टर

7

निष्पादित करने पर: for /f %%i in ('application arg0 arg1') do set VAR=%%iमुझे त्रुटि मिल रही थी: %% मैं इस समय अप्रत्याशित था। एक फिक्स के रूप में, मुझे ऊपर के रूप में निष्पादित करना पड़ाfor /f %i in ('application arg0 arg1') do set VAR=%i


9
एक बैच फ़ाइल में आपको ज़रूरत होती है %%और कमांड लाइन पर एक बैच फ़ाइल के बाहर आपको ज़रूरत होती है%
जेरी जेरेमिया

2

उत्तर के अलावा, आप सीधे लूप के सेट भाग में आउटपुट पुनर्निर्देशन ऑपरेटरों का उपयोग नहीं कर सकते हैं for(जैसे कि यदि आप किसी उपयोगकर्ता से स्ट्रैडर आउटपुट छुपाना चाहते हैं और एक अच्छा त्रुटि संदेश प्रदान करते हैं)। इसके बजाय, आपको उन्हें कैरट चरित्र के साथ बचना होगा ( ^):

for /f %%O in ('some-erroring-command 2^> nul') do (echo %%O)

संदर्भ: बैच स्क्रिप्ट के लूप के लिए कमांड का रीडायरेक्ट आउटपुट


1
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

REM Prefer backtick usage for command output reading:
REM ENABLEDELAYEDEXPANSION is required for actualized
REM  outer variables within for's scope;
REM within for's scope, access to modified 
REM outer variable is done via !...! syntax.

SET CHP=C:\Windows\System32\chcp.com

FOR /F "usebackq tokens=1,2,3" %%i IN (`%CHP%`) DO (
    IF "%%i" == "Aktive" IF "%%j" == "Codepage:" (
        SET SELCP=%%k
        SET SELCP=!SELCP:~0,-1!
    )
)
echo actual codepage [%SELCP%]

ENDLOCAL

(प्लस 1) बैकटिक्स स्पष्टीकरण के लिए
सैंडबर्ग

1

आप कमांड आउटपुट के सरल कैप्चरिंग के लिए बैच मैक्रो का उपयोग कर सकते हैं, थोड़ा सा बैश शेल के व्यवहार की तरह।

मैक्रो का उपयोग सरल है और जैसा दिखता है

%$set% VAR=application arg1 arg2

और यह पाइप के साथ भी काम करता है

%$set% allDrives="wmic logicaldisk get name /value | findstr "Name""

मैक्रो एक सरणी की तरह चर का उपयोग करता है और प्रत्येक पंक्ति को एक अलग सूचकांक में संग्रहीत करता है।
वहाँ के नमूने में %$set% allDrives="wmic logicaldiskनिम्नलिखित चर बनाए जाएंगे:

allDrives.Len=5
allDrives.Max=4
allDrives[0]=Name=C:
allDrives[1]=Name=D:
allDrives[2]=Name=F:
allDrives[3]=Name=G:
allDrives[4]=Name=Z:
allDrives=<contains the complete text with line feeds>

इसका उपयोग करने के लिए, यह समझना महत्वपूर्ण नहीं है कि मैक्रो स्वयं कैसे काम करता है।

पूरा उदाहरण

@echo off
setlocal

call :initMacro

%$set% ipOutput="ipconfig"
call :ShowVariable ipOutput
echo First line is %ipOutput[0]%

echo( 
%$set% driveNames="wmic logicaldisk get name /value | findstr "Name""
call :ShowVariable driveNames

exit /b

:ShowVariable
setlocal EnableDelayedExpansion
for /L %%n in (0 1 !%~1.max!) do (
    echo %%n: !%~1[%%n]!
)
echo(
exit /b

:initMacro
if "!!"=="" (
    echo ERROR: Delayed Expansion must be disabled while defining macros
    (goto) 2>nul
    (goto) 2>nul
)
(set LF=^
%=empty=%
)
(set \n=^^^
%=empty=%
)

set $set=FOR /L %%N in (1 1 2) dO IF %%N==2 ( %\n%
    setlocal EnableDelayedExpansion                                 %\n%
    for /f "tokens=1,* delims== " %%1 in ("!argv!") do (            %\n%
        endlocal                                                    %\n%
        endlocal                                                    %\n%
        set "%%~1.Len=0"                                            %\n%
        set "%%~1="                                                 %\n%
        if "!!"=="" (                                               %\n%
            %= Used if delayed expansion is enabled =%              %\n%
                setlocal DisableDelayedExpansion                    %\n%
                for /F "delims=" %%O in ('"%%~2 | findstr /N ^^"') do ( %\n%
                if "!!" NEQ "" (                                    %\n%
                    endlocal                                        %\n%
                    )                                               %\n%
                setlocal DisableDelayedExpansion                    %\n%
                set "line=%%O"                                      %\n%
                setlocal EnableDelayedExpansion                     %\n%
                set pathExt=:                                       %\n%
                set path=;                                          %\n%
                set "line=!line:^=^^!"                              %\n%
                set "line=!line:"=q"^""!"                           %\n%
                call set "line=%%line:^!=q""^!%%"                   %\n%
                set "line=!line:q""=^!"                             %\n%
                set "line="!line:*:=!""                             %\n%
                for /F %%C in ("!%%~1.Len!") do (                   %\n%
                    FOR /F "delims=" %%L in ("!line!") Do (         %\n%
                        endlocal                                    %\n%
                        endlocal                                    %\n%
                        set "%%~1[%%C]=%%~L" !                      %\n%
                        if %%C == 0 (                               %\n%
                            set "%%~1=%%~L" !                       %\n%
                        ) ELSE (                                    %\n%
                            set "%%~1=!%%~1!!LF!%%~L" !             %\n%
                        )                                           %\n%
                    )                                               %\n%
                    set /a %%~1.Len+=1                              %\n%
                )                                                   %\n%
            )                                                       %\n%
        ) ELSE (                                                    %\n%
            %= Used if delayed expansion is disabled =%             %\n%
            for /F "delims=" %%O in ('"%%~2 | findstr /N ^^"') do ( %\n%
                setlocal DisableDelayedExpansion                    %\n%
                set "line=%%O"                                      %\n%
                setlocal EnableDelayedExpansion                     %\n%
                set "line="!line:*:=!""                             %\n%
                for /F %%C in ("!%%~1.Len!") DO (                   %\n%
                    FOR /F "delims=" %%L in ("!line!") DO (         %\n%
                        endlocal                                    %\n%
                        endlocal                                    %\n%
                        set "%%~1[%%C]=%%~L"                        %\n%
                    )                                               %\n%
                    set /a %%~1.Len+=1                              %\n%
                )                                                   %\n%
            )                                                       %\n%
        )                                                           %\n%
        set /a %%~1.Max=%%~1.Len-1                                  %\n%
)                                                                   %\n%
    ) else setlocal DisableDelayedExpansion^&set argv=

goto :eof

0

मैंने स्क्रिप्ट लिखी है जो google.com को हर 5 सेकंड में पिंग करता है और वर्तमान समय के साथ परिणाम लॉग करता है। यहाँ आप चर के लिए आउटपुट पा सकते हैं "कमांडलाइन" (सूचकांकों के साथ)

@echo off

:LOOPSTART

echo %DATE:~0% %TIME:~0,8% >> Pingtest.log

SETLOCAL ENABLEDELAYEDEXPANSION
SET scriptCount=1
FOR /F "tokens=* USEBACKQ" %%F IN (`ping google.com -n 1`) DO (
  SET commandLineStr!scriptCount!=%%F
  SET /a scriptCount=!scriptCount!+1
)
@ECHO %commandLineStr1% >> PingTest.log
@ECHO %commandLineStr2% >> PingTest.log
ENDLOCAL

timeout 5 > nul

GOTO LOOPSTART
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.