How to set batch variable to output of another scr

2019-03-02 18:56发布

I try to set a batch variable to an output of another command. In Linux/Unix you can simply use backticks, e.g. (in csh)

set MY_VAR = `tail /etc/passwd`

Is there something similar available in windows batch?

Actually I found already something but it is not fully working:

d:\>for /F "skip=1" %n in ('wmic OS Get CurrentTimeZone') do set TimeZone=%n

d:\>set TimeZone=120

 :\>set TimeZone=

d:\>

The problem is the wmic commands returns several lines, otherwise it would work fine. The first I know to skip, however I did not manage to skip the second empty line. I tried with IF but no success.

3条回答
做自己的国王
2楼-- · 2019-03-02 19:29

I suggest following batch code:

@echo off
for /F "skip=1" %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS Get CurrentTimeZone') do (
   set "TimeZone=%%I"
   goto BelowLoop
)
:BelowLoop
echo Time zone difference is: %TimeZone%

The FOR loop is exited with command GOTO after the value of interest is assigned to environment variable TimeZone.

The entire FOR loop can be optimized to a single command line:

@echo off
for /F "skip=1" %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS Get CurrentTimeZone') do set "TimeZone=%%I" & goto BelowLoop
:BelowLoop
echo Time zone difference is: %TimeZone%

Exiting the FOR loop after having the value of interest avoids the problem with wrong parsing of Unicode (UTF-16 Little Endian) encoded output of WMIC by FOR which otherwise would result in deleting the environment variable TimeZone. For details on wrong parsing of Unicode output by FOR see answer on How to correct variable overwriting misbehavior when parsing output?

查看更多
小情绪 Triste *
3楼-- · 2019-03-02 19:30

yes - the output of wmic is a bit ugly to handle.

Use a trick: search for a number in the ouput (findstr "[0-9] will only return lines, that contain a number):

for /F %n in ('wmic OS Get CurrentTimeZone ^|findstr "[0-9]"') do set TimeZone=%n
echo Timezone is %TimeZone%.

(for use in a batchfile use %%n instead of %n)

Another way is:

for /F %n in ('wmic OS Get CurrentTimeZone') do if not defined TimeZone set TimeZone=%n

EDIT:

I prefer the first version, as findstr (or find) converts the wmic-line-endings, so the second for mentioned by MC ND is not neccessary.

查看更多
一夜七次
4楼-- · 2019-03-02 19:38
for /f "tokens=2 delims==" %a in ('wmic OS get CurrentTimeZone /value') do set "timeZone=%a"

(to use in a batch file, remember to double the percent signs)

The added /value in wmic changes its output to key=value format. The delims clause in for command indicates a = as a separator. The tokens clause ask to retrieve only the second token/field in the line. As the only line with two tokens is the line with the required data, only this line is processed.

BUT, wmic output includes an aditional carriage return at the end of its output, that needs to be removed from the variable. An aditional for command can be used. The resulting command will be

for /f "tokens=2 delims==" %a in ('wmic OS get CurrentTimeZone /value') do for /f %b in ("%a") do set "timeZone=%b"

Or, for a batch file

    for /f "tokens=2 delims==" %%a in (
        'wmic OS get CurrentTimeZone /value'
    ) do for /f %%b in ("%%a") do set "timeZone=%%b"

    echo %timeZone%
查看更多
登录 后发表回答