Remove unwanted spaces in wmic results through bat

2019-07-29 10:07发布

问题:

Im working on a batch file in which I need to show the estimated charge remaining of the battery, I have achieved my goal but sadly I am not happy with the results due to excesive and unwanted spaces in the command result.

Here's my code:

:charge
FOR /F "delims= skip=1" %%i IN ('WMIC PATH Win32_Battery Get EstimatedChargeRemaining') DO ( SET CHR=%%i
GOTO results )

:results
ECHO "Battery Percentage: %CHR%"
PAUSE
GOTO menu

The result of the above command is: "Battery Percentage: 100 "

How do I get rid of those spaces at the end of the result?

Thanks in advance and any kind of help is greatly appreciated.

回答1:

try like this:

:charge
@echo off
FOR /F "tokens=* delims=" %%i IN ('WMIC PATH Win32_Battery Get EstimatedChargeRemaining /format:value') DO (
    for /f "tokens=* delims=" %%# in ("%%i") do set "%%#"
)
echo %EstimatedChargeRemaining%

WMIC adds additional character but it can be removed with one more for loop -> https://www.dostips.com/forum/viewtopic.php?t=4266



回答2:

I do not understand why you ask basically the same question twice...

Anyway, to keep the long story short: wmic returns Unicode text, while for /F is made for ASCII/ANSI text. for /F converts the Unicode text to ANSI, but leaves conversion artefacts like orphaned carriage-return characters behind. These are the reason why there seems to be output empty lines past the (last) data line. The trailing SPACEs are not conversion artefacts though, they are really output by the wmic command.

For instance, the command line:

for /F "delims=" %%I in ('wmic Path Win32_Battery get EstimatedChargeRemaining') do echo/%%I

...outputs something like the following text ({CR} stands for a carriage-return character and {SPACE} for a SPACE):

EstimatedChargeRemaining{SPACE}{SPACE}{CR}
100{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{CR}
{CR}

Wrapping around another for /F loop removes those carriage-return characters, so the command line:

for /F "delims=" %%I in ('wmic Path Win32_Battery get EstimatedChargeRemaining') do (
    for /F "delims=" %%J in ("%%I") do echo/%%J
)

...would output something like this:

EstimatedChargeRemaining{SPACE}{SPACE}
100{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}{SPACE}

As you can see, the carriage-return characters disappear, and so does the very last line (which you skip over by the goto return command in your code). Any trailing SPACEs are still there though. However, such can be gotten rid of by adapting the tokens and delims options of for /F adequately:

rem // Skip the header line by `skip` option in the outer loop; do not tokenise anything here:
for /F "skip=1 delims=" %%I in ('wmic Path Win32_Battery get EstimatedChargeRemaining') do (
    rem /* Tokenise the output as needed in the inner loop;
    rem    remember that `tokens` defaults to `1` and `delims` defaults to SPACE and TAB: */
    for /F %%J in ("%%I") do echo/%%J
)

The output is going to be something like (without any trailing SPACEs this time):

100

An even better way, particularly when the data returned by wmic might contain SPACEs on their own, is to change the output format of the wmic command using the /VALUE option, which does not produce trailing spaces.

For instance, the command line:

for /F "delims=" %%I in ('wmic Path Win32_Battery get EstimatedChargeRemaining /VALUE') do echo/%%I

...outputs something like the following text ({CR} stands for a carriage-return character):

{CR}
{CR}
EstimatedChargeRemaining=100{CR}
{CR}
{CR}
{CR}

Again wrapping around another for /F loop removes those carriage-return characters, so the command line:

for /F "delims=" %%I in ('wmic Path Win32_Battery get EstimatedChargeRemaining /VALUE') do (
    for /F "delims=" %%J in ("%%I") do echo/%%J
)

...would output something like this:

EstimatedChargeRemaining=100

Also here, the carriage-return characters disappear, and so do all the lines that just contain one such character. Note that there are no trailing SPACEs at all. Now you just have to split off the name of the value:

rem // Do not tokenise anything in the outer loop:
for /F "delims=" %%I in ('wmic Path Win32_Battery get EstimatedChargeRemaining /VALUE') do (
    rem /* Tokenise the output as needed in the inner loop: */
    for /F "tokens=1* delims==" %%J in ("%%I") do echo/%%K
)

The output is going to be something like:

100

This method failed in case the value began with an equal-to sign though. To handle such properly, you could do this:

for /F "delims=" %%I in ('wmic Path Win32_Battery get EstimatedChargeRemaining /VALUE') do (
    for /F "delims=" %%J in ("%%I") do (
        rem // Store whole line in a variable:
        set "VALUE=%%K"
        rem // Toggle delayed expansion to not lose exclamation marks:
        setlocal EnableDelayedExpansion
        rem // Split off value name:
        set "VALUE=!VALUE:*EstimatedChargeRemaining=!"
        rem // Split off leading `=`:
        echo(!VALUE:~1!
        endlocal
    )
)