मुझे विंडोज़ में एक चर में एक कमांड का परिणाम कैसे मिलेगा?


132

मैं विंडोज बैच स्क्रिप्ट में एक चर के रूप में एक कमांड का परिणाम प्राप्त करने के लिए देख रहा हूं (देखें कि कैसे बैश स्क्रिप्टिंग समकक्ष के लिए बैश में कमांड का परिणाम प्राप्त किया जा सकता है )। एक .bat फ़ाइल में काम करने वाला समाधान पसंद किया जाता है, लेकिन अन्य सामान्य विंडोज़ स्क्रिप्टिंग समाधान भी स्वागत योग्य हैं।


9
जॉन, यह बहुत उपयोगी सवाल खोजने के लिए हास्यास्पद है । क्या आप कृपया एक वैकल्पिक विकल्प को जोड़ने पर विचार कर सकते हैं जैसे कि विंडोज बैच फ़ाइल में चर में प्रोग्राम के आउटपुट को कैसे कैप्चर किया जाए ?
पायोत्र डोब्रोगोस्ट

3
Google ने इस पेज को 3rd रैंक दिया।
रेने न्यफेनेगर


@MichaelFreidgeim यह प्रश्न वास्तव में उस डुप्लिकेट से 2 साल पहले पूछा गया था - लेकिन इस प्रश्न के कई डुप्लिकेट हैं। पर टिप्पणी देखें stackoverflow.com/questions/6359820/...
icc97

1
@ icc97, "संभावित डुप्लिकेट" सफाई का एक तरीका है - समान प्रश्नों को बंद करना और सबसे अच्छे उत्तरों के साथ एक रखना। तारीख जरूरी नहीं है। Meta.stackexchange.com/questions/147643/… देखें यदि आप सहमत हैं कि इसके लिए स्पष्टीकरण की आवश्यकता है, तो कृपया meta.stackexchange.com/questions/281980/ पर वोट करें यदि आप कई डुप्लिकेट देखते हैं, तो आपको एक के रूप में चयन करना चाहिए और दूसरे को बंद करने के लिए विहित और वोट के रूप में चुनना चाहिए। ।
माइकल फ्रीजिम

जवाबों:


34

यदि आपको सभी कमांड आउटपुट कैप्चर करने हैं, तो आप इस तरह से एक बैच का उपयोग कर सकते हैं:

@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 में "!" के साथ अलग किया जाता है।

@ जॉन: क्या इसके लिए कोई व्यावहारिक उपयोग है? मुझे लगता है कि आपको आसानी से स्क्रिप्टिंग कार्य करने में सक्षम पावरशेल या किसी अन्य प्रोग्रामिंग भाषा को देखना चाहिए (पायथन, पर्ल, पीएचपी, रबड)


एकल पंक्ति का उत्तर मेरे पास मौजूद विशिष्ट मामले को हल करेगा। मुझे लगा कि एक बहु-पंक्ति विकल्प (या एक आसान एकल पंक्ति विकल्प) था। मुझे लगता है कि बल्लेबाजी की क्षमताओं की क्षमता सिर्फ इतनी महान नहीं है। इसके लिए जरूरत जावा एप्स को रैप करने वाली बैट स्क्रिप्ट की है। मुख्य रूप से क्लासपाथ का निर्माण।
जॉन मेघेर

उससे बहुत सावधान रहना चाहिए। GWT ने जावा को विशिष्ट क्लासपैथ के साथ शुरू करने के लिए बैच फ़ाइलों का उपयोग करने का भी प्रयास किया, जो कि जैसे ही आप गैर-एएससीआईआई पात्रों के साथ निर्देशिकाओं में प्राप्त कर रहे थे (उस स्थिति में यह मेरा घर था) विफल हो गया। उन्होंने वीबीएस के साथ फिर से लिखा।
जोए

25
क्या इसके लिए कोई व्यावहारिक उपयोग है? क्या तुम मजाक कर रहे हो? इसका उपयोग हर समय अन्य गोले (सभी GNU / लिनक्स वाले जो मुझे लगता है) में किया जाता है और यह बहुत उपयोगी है।
पायोत्र डोब्रोगोस्ट

1
@PiotrDobrogost मुझे लगता है कि वह क्या कहना चाह रहा था कि बैश स्क्रिप्ट अतीत का एक भयानक अवशेष है (आपको किसी प्रोग्राम के आउटपुट को कैप्चर करने के लिए लूप के लिए उपयोग करने की आवश्यकता है ? गंभीरता से?), और यदि आप कभी भी इस बिंदु पर पहुंचते हैं? जहाँ आप अपने आप को चर का उपयोग करने की आवश्यकता पाते हैं, आपको कुछ और आधुनिक जैसे पॉवरशेल का उपयोग करना चाहिए।
अजेदी32

3
एक व्यावहारिक उपयोग है, वास्तव में ... थोड़े। मैं किसी विशेष Visual Studio पथ को खोजने के लिए PowerShell स्क्रिप्ट का उपयोग करना चाहता हूं, लेकिन मुझे उस पथ से जिस चीज़ की आवश्यकता है वह एक बैच फ़ाइल है जो env vars का एक समूह सेट करता है इसलिए मैं editbin कह सकता हूं ... इसलिए मुझे पथ खोजने की आवश्यकता है और इसे कॉलिंग इंस्टेंस पर वापस लाएं cmdताकि मैं इसे वहां चला सकूं। ... हाँ, यह आवाज़ जितनी भयानक है। विजुअल स्टूडियो मुझे कभी-कभी रोना चाहता है। @ Ajedi32 मुझे लगता है कि आपके कहने का मतलब है कि बैच स्क्रिप्ट अतीत का एक भयानक अवशेष है। ;)
jpmc26

85

कमांड के लिए विनम्र वर्षों में कुछ दिलचस्प क्षमता जमा हुई है:

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

ध्यान दें कि "delims="डिफ़ॉल्ट स्थान और टैब सीमांकक को ओवरराइट कर देता है ताकि दिनांक कमांड का आउटपुट एक ही बार में प्राप्त हो जाए।

मल्टी-लाइन आउटपुट कैप्चर करने के लिए, यह अनिवार्य रूप से एक-लाइनर हो सकता है (परिणामस्वरूप चर में सीमांकक के रूप में परिसीमक का उपयोग करके):

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"

1
@ पाब्लो के उत्तर के साथ, यह केवल इस मामले में कमांड की अंतिम पंक्ति "तिथि / टी" से प्राप्त करने के लिए काम करेगा।
जॉन मेघेर

11
मुझे आपका जवाब काम करने के लिए मिला जब मैंने दोहरे प्रतिशत संकेतों का उपयोग किया, अर्थातFOR /F "delims=" %%i IN ('date /t') DO set today=%%i
Rabarberski

18
@ रबारकी: यदि आप forकमांड लाइन पर सीधे कमांड टाइप करते हैं , तो आप सिंगल का उपयोग करते हैं %। यदि आप इसे बैच फ़ाइल में उपयोग करते हैं, तो आप उपयोग करते हैं %%
इंडिविप

@tardate: क्या आप बता सकते हैं कि स्क्रिप्ट कैसी लगेगी, यदि कमांड को तर्क के साथ पारित करने की आवश्यकता है %, उदाहरण के लिए:for /f "delims=" %%i in ('date +%F_%H-%M-%S') do set now=%%i
dma_k

1
@degenerate कमांड वैध है बशर्ते कि dateइस्तेमाल की गई कमांड Cygwin से आती हो। मैं मानता हूं कि मुझे इसका उल्लेख करना चाहिए था।
dma_k

24

वर्तमान निर्देशिका प्राप्त करने के लिए, आप इसका उपयोग कर सकते हैं:

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

लेकिन आप एक और अधिक शक्तिशाली शेल पर जाने या इस सामान के लिए एक एप्लिकेशन बनाने पर विचार कर सकते हैं। यह बैच फ़ाइलों की संभावनाओं को काफी बढ़ा रहा है।


क्या कोई भिन्नता है जो कमांड से कई लाइनों को पकड़ने के लिए काम करेगी?
जॉन मेघेर

6
वर्तमान निर्देशिका को प्राप्त करने के लिए आप इको% CD%
जो

9

आपको SETपैरामीटर के साथ कमांड का उपयोग करने /Pऔर अपने आउटपुट को इसे निर्देशित करने की आवश्यकता है। उदाहरण के लिए http://www.ss64.com/nt/set.html देखें । सीएमडी के लिए काम करेगा, निश्चित नहीं। बीएटी फाइलों के बारे में

एक टिप्पणी से इस पोस्ट के लिए:

उस लिंक में कमांड है " Set /P _MyVar=<MyFilename.txt" जो कहता है कि यह _MyVarपहली पंक्ति से सेट होगा MyFilename.txt। यह " myCmd > tmp.txt" के साथ " set /P myVar=<tmp.txt" के रूप में इस्तेमाल किया जा सकता है । लेकिन यह केवल आउटपुट की पहली पंक्ति प्राप्त करेगा, सभी आउटपुट नहीं


2
उस लिंक में "Set / P _MyVar = <MyFilename.txt" कमांड है, जो कहता है कि यह MyFilename.txt से पहली पंक्ति में _MyVar सेट करेगा। इसे "सेट / पी myVar = <tmp.txt" के साथ "myCmd> tmp.txt" के रूप में इस्तेमाल किया जा सकता है। लेकिन यह केवल आउटपुट की पहली पंक्ति प्राप्त करेगा, सभी आउटपुट नहीं।
जॉन मेघेर

यह उत्तर खुद जैसे भिखारियों के लिए है

5

"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

2
मैंने पहले भी इस दृष्टिकोण को देखा है, लेकिन ऐसा लगता है कि यह बहुत ही हैकिंग है। इसमें यह भी समस्या है कि यह केवल चर में कमांड से आउटपुट की अंतिम पंक्ति को कैप्चर करेगा।
जॉन मेघेर

3

केवल FORकमांड से परिणाम का उपयोग करें । उदाहरण के लिए (एक बैच फ़ाइल के अंदर):

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

आप अपनी %%Iइच्छानुसार मूल्य का उपयोग कर सकते हैं। बस ऐसे ही %%I:।

और अग्रिम में %%Iकोई स्थान या सीआर वर्ण नहीं है और तुलना के लिए इस्तेमाल किया जा सकता है !!


2

यदि आप बैश में एक तर्क के रूप में एक कमांड के परिणाम का उपयोग करके प्रदान किए गए समाधान की तलाश कर रहे हैं ?

फिर यहाँ कोड है:

@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
  • यह सीडी कमांड के परिणाम के साथ खुद को कॉल करेगा, वही pwd के रूप में।
  • मापदंडों पर स्ट्रिंग निष्कर्षण फ़ाइल नाम / फ़ोल्डर वापस कर देगा।
  • इस फ़ोल्डर की सामग्री प्राप्त करें और filename.txt में जोड़ें

[क्रेडिट] : अन्य सभी जवाब और विंडोज एक्सपी कमांड पेज पर कुछ खुदाई के लिए धन्यवाद ।


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%"

उत्तर पोस्ट करने के लिए धन्यवाद! हालांकि एक कोड स्निपेट प्रश्न का उत्तर दे सकता है, फिर भी इसके अलावा कुछ और जानकारी जोड़ने के लिए बहुत अच्छा है, जैसे कि स्पष्टीकरण, आदि ..
j0k

2

मैं उपरोक्त समाधानों के लिए एक टिप्पणी जोड़ना चाहूंगा:

ये सभी वाक्यविन्यास पूरी तरह से अच्छी तरह से काम करते हैं, अगर आपके कमेंट में पैठ है या फिर अगर कमोड SPACES या स्पेशल चार्जर्स के बिना एक cmdpath है।

लेकिन यदि आप किसी फ़ोल्डर में स्थित निष्पादन योग्य कमांड का उपयोग करने का प्रयास करते हैं जिसमें पथ में विशेष वर्ण हैं तो आपको अपने कमांड पथ को दोहरे उद्धरण चिह्नों (") में संलग्न करना होगा और फिर 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.

उस स्थिति में, एक कमांड का उपयोग करने और वेरिएबल में इसके परिणाम को स्टोर करने के लिए एकमात्र एकमात्र समाधान यह है कि डिफॉल्ट डायरेक्टरी को एक ही कमांड में सेट करें (अस्थायी रूप से):

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 है। मैंने इसे वेब साइट f2ko.de ( http://f2ko.de/en/cmd.php ) पर पाया ।

यदि किसी के पास एक जटिल मार्ग के माध्यम से सुलभ उस प्रकार के आदेशों के लिए एक बेहतर समाधान है, तो मुझे यह सुनकर बहुत खुशी होगी।

गाइल्स


आप के साथ अपने आदेश उपसर्ग कर सकते हैं CALLयदि पथ में रिक्त स्थान है तो for / F काम नहीं करता है
jeb

@ जैब: आपको बहुत अच्छा लगा! अब मेरा कोड < CALL "%SOURCEDIR%\FOLDERBROWSE" ... "quoted parameters"> पूरी तरह से काम करता है।
गाइल्स माइसन्यूव

1

आप सभी आउटपुट को एक चर में कैप्चर कर सकते हैं, लेकिन वास्तविक सीआर-एलएफ के बजाय लाइनों को आपकी पसंद के चरित्र (# नीचे दिए गए उदाहरण में) से अलग किया जाएगा।

@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%

दूसरा संस्करण, यदि आपको सामग्री को लाइन-बाय-लाइन प्रिंट करने की आवश्यकता है। यह इस तथ्य से प्रभावित है कि "डीआईआर / बी" से आउटपुट की डुप्लिकेट लाइनें नहीं होंगी, इसलिए यह सामान्य स्थिति में काम नहीं कर सकता है।

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

0
@echo off
setlocal EnableDelayedExpansion
FOR /F "tokens=1 delims= " %%i IN ('echo hola') DO (
    set TXT=%%i
)
echo 'TXT: %TXT%'

परिणाम 'TXT: होला' है


0

आपको forकमांड का उपयोग करना चाहिए , यहाँ एक उदाहरण है:

@echo off
rem Commands go here
exit /b
:output
for /f "tokens=* useback" %%a in (`%~1`) do set "output=%%a"

और आप उपयोग कर सकते हैं call :output "Command goes here"तब आउटपुट %output%वेरिएबल में होगा ।

नोट: यदि आपके पास एक कमांड आउटपुट है जो मल्टीलाइन है, तो यह टूल setआउटपुट को आपके मल्टीलाइन कमांड की अंतिम पंक्ति तक ले जाएगा।


-1

कृपया इस http://technet.microsoft.com/en-us/library/bb490982.aspx को देखें जो बताता है कि आप कमांड आउटपुट के साथ क्या कर सकते हैं।


1
वह लेख सिर्फ पुनर्निर्देशन और संबंधित विषयों को शामिल करता है। यह इस सवाल का जवाब नहीं देता है कि एक कमांड के आउटपुट को कैसे लिया जाए और इसे एक चर में लाया जाए।
जॉन मेघेर

3
उनके जवाब का उपयोग करते हुए मैं इस पर आया git pull>0 set /P RESULTVAR=<0 हूं : संपादित करें: मुझे लगता है, मुझे नहीं पता कि यहां लाइन ब्रेक का उपयोग कैसे किया जाए ... प्रत्येक कमांड स्वयं की लाइन पर है।
RibeiroBreno
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.