0

I'm rewriting batch file for counting page file usage to the one-liner:

@ECHO OFF
for /f "tokens=1,2 skip=2 delims==" %%a in ('wmic pagefile list /format:list') do (
IF "%%a"=="AllocatedBaseSize" SET TOTAL=%%b
IF "%%a"=="CurrentUsage" SET USAGE=%%b
)
SET TOTAL
SET USAGE
set /a perc = 100 * USAGE / TOTAL
echo used: %perc%%%

----- OUTPUT -----

TOTAL=4095
USAGE=728
used: 17%

So far I was able to mimic it with:

(for /f "tokens=1,2 skip=2 delims==" %a in ('wmic pagefile list /format:list') do @(IF "%a"=="AllocatedBaseSize" (SET TOTAL=%b) ELSE (IF "%a"=="CurrentUsage" SET USAGE=%b)))  & SET TOTAL & SET USAGE & set /A perc=100*USAGE/TOTAL & echo|set /p dummy=% of usage

----- OUTPUT -----
TOTAL=4095
USAGE=724
17% of usage

But only because I'm using very ugly hack echo|set /p dummy=% of usage. My problem is when I tried just echo %perc%% it will print %perc%%. So now I'm just appending "of usage" to set /A's output - first because it seems that it's not possible to omit this output according to documentation set /?:

If SET /A is executed from the command line outside of a command script, then it displays the final value of the expression.

and second because I can not print the value of perc variable.

For clarity my problem can be simplified to:

C:\>set x=1 & echo %x%
%x%
C:\>echo %x%
1

Any help / explanation is welcomed.

Tried SetX variable value also.

A.D.
  • 4,487
  • 3
  • 38
  • 50
  • At the end of writing this I got idea to spawn new shell: `(for /f "tokens=1,2 skip=2 delims==" %a in ('wmic pagefile list /format:list') do @(IF "%a"=="AllocatedBaseSize" (SET TOTAL=%b) ELSE (IF "%a"=="CurrentUsage" SET USAGE=%b))) & SET TOTAL & SET USAGE & set /A perc=100*USAGE/TOTAL & cmd /K "echo usage is %perc%%"` and it is of course working, but still `set /A` is outputting unwanted string. Too tired now - but on the right way ;) – A.D. Nov 11 '14 at 04:36
  • 2
    From the command line, execute: `cmd /V:ON /C set /A x=2-1 ^>NUL ^& echo !x!` and it will display: `1`. This way also works: `cmd /V:ON /C "set /A x=2-1 >NUL & echo !x!"` – Aacini Nov 11 '14 at 05:11

2 Answers2

1

Change the line

set x=1 & echo %x%

to

setlocal EnableDelayedExpansion
set "x=1" & echo !x!

and command echo outputs 1 as expected.

cmd.exe replaces all references to environment variables already by their current value before executing a line or a block enclosed in parentheses. Therefore it is necessary to use delayed environment variable expansion enabled with setlocal EnableDelayedExpansion and using ! instead of % around the variable reference in this case where the variable value is modified/set on same line respectively in same block.

And use double quotes around variable=value as demonstrated here. Another example:

set /A "perc=100*USAGE/TOTAL"
Mofi
  • 46,139
  • 17
  • 80
  • 143
  • 1
    that won't work in a one-liner, as the variables get evaluated before `setlocal` gets executed. – Stephan Nov 11 '14 at 07:22
  • Stephan is right, I tried `setlocal EnableDelayedExpansion` before, just try it on your own @Mofi `setlocal EnableDelayedExpansion & set "x=1" & echo !x!` – A.D. Nov 12 '14 at 04:20
  • Yes, as I wrote my answer I knew what [Stephan](http://stackoverflow.com/users/2152082/stephan) wrote which was the reason why my code snippet contains 2 lines. It looks like I should have explicitly explain that first line and second line cannot be combined to a single line. In the meantime [MC ND](http://stackoverflow.com/users/2861476/mc-nd) posted a single line solution. Delayed expansion can be enabled by default in Windows registry, see Microsoft article about [DelayedExpansion](http://technet.microsoft.com/en-us/library/cc957361.aspx) registry value. – Mofi Nov 12 '14 at 08:31
  • [A.D.](http://stackoverflow.com/users/1136008/a-d), my answer contains just the explanation why your one-liner fails as you wanted to know according to your question. You have not asked explicitly for a working one-liner solution. Well, your question does not contain any question at all. – Mofi Nov 12 '14 at 08:36
  • Ok I get it now. On first sight it looks like you are proposing something which can not be used (in my case). `cmd /V:ON` is the key which I was not aware of and it would perfectly make sense to mention it when you talk about `setlocal EnableDelayedExpansion`. I mean - you are answering "why" without working example - the "how" (implicitly asked). – A.D. Nov 13 '14 at 04:28
  • And your point about "any question" is right, my post doesn't even have any question mark :) My fault, in my next questions I will try to be more cautious. Or I will not ask q at the end of my night shift ;) – A.D. Nov 13 '14 at 04:29
1
cmd /v:on /c "for /f "skip=2 tokens=2,3 delims=," %a in ('wmic pagefile get allocatedbasesize^,currentusage^,status /format:csv') do @(set /a "pct=%b*100/%a">nul & echo total: %a & echo usage: %b & echo used : !pct!^%)"
MC ND
  • 69,615
  • 8
  • 84
  • 126
  • Very nice. Different approach from which I will learn a lot. Thanks! – A.D. Nov 12 '14 at 04:24
  • BTW as usual I ran from one problem to another because [Win7 has some bug](http://stackoverflow.com/a/18284780/1136008) so I had to customize `wmic` query to `wmic pagefile get allocatedbasesize^,currentusage^,status /format:"%WINDIR%\System32\wbem\en-us\csv"` – A.D. Nov 12 '14 at 04:26