2

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.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
Minnen
  • 441
  • 8
  • 27
  • 3
    `... DO ( SET /a CHR=%%I` (also removes that ugly and disturbing `CR`) – Stephan Nov 29 '18 at 15:03
  • 1
    I'd use `for /F "skip=1 delims=" %%I in ('wmic path Win32_Battery get EstimatedChargeRemaining') do for /F %%J in ("%%I") do set "CHR=%%i"` in order to avoid the trailing spaces and conversion problems from Unicode to ANSI, hence no `goto :results` is necessary anymore. This is a more generic solution not just working for integer values... – aschipfl Nov 29 '18 at 15:12
  • @Stephan your awnser was exactly what i needed, thanks i do not know how to close this question from your awnser but this solved my issue – Minnen Nov 29 '18 at 15:15
  • keep in mind, that is a very simple solution, working only for Integer output. In general, the suggestion from aschipfl is better. – Stephan Nov 29 '18 at 15:37
  • @aschipfl yesterday I "borrowed" some code from you to complete my answer. Feel free to convert your comment to an answer and add my simplified solution as "especially for this case". – Stephan Nov 29 '18 at 15:39
  • 1
    [Combine Batch/WMIC + ANSI/UNICODE Output formatting](https://superuser.com/q/812438/241386), [Editing WMIC output format](https://stackoverflow.com/q/19462042/995714), [Mixed ascii and unicode output from script - how to get command to output all as ascii?](https://stackoverflow.com/q/44065913/995714) – phuclv Nov 29 '18 at 16:45
  • 1
    Possible duplicate of [Mixed ascii and unicode output from script - how to get command to output all as ascii?](https://stackoverflow.com/questions/44065913/mixed-ascii-and-unicode-output-from-script-how-to-get-command-to-output-all-as) – phuclv Nov 29 '18 at 16:45

2 Answers2

5

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

npocmaka
  • 55,367
  • 18
  • 148
  • 187
  • 2
    One more wonderful working solution for this issue in addition to the solutions posted on additional question [Why is the error message “Missing operand” output on processing WMIC output and assigning a value to a variable?](https://stackoverflow.com/questions/53546076/) of original poster of this question. – Mofi Nov 29 '18 at 22:11
3

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
    )
)
aschipfl
  • 33,626
  • 12
  • 54
  • 99