Can a wmic processes table (within the command prompt window) be sorted by a value?

走远了吗. 提交于 2019-12-07 13:41:41

问题


I've been exploring various options, such as the /format flag, however it appears that sorting is only possible in XML or HTML output. I would like to sort within command prompt itself. It seems that even TaskList cannot do this (and I would prefer to use wmic since it seems to perform faster).

An example of a command to run would be wmic process get name,processid,workingsetsize. Processes appear to be sorted by processid, but it would make much more sense (in my use case, at least) to sort by name or memory usage (workingsetsize).

As requested, here's an example wmic process table output:

Name                          ProcessId  WorkingSetSize
System Idle Process           0          20480
System                        4          765952
smss.exe                      384        393216
csrss.exe                     500        2850816
wininit.exe                   596        774144
csrss.exe                     612        6230016
winlogon.exe                  672        2023424
services.exe                  696        7192576
lsass.exe                     704        9814016
svchost.exe                   820        5287936
svchost.exe                   872        7454720
atiesrxx.exe                  936        1028096

Obviously, process lists can get very long, so I've cut it off there.


回答1:


@ECHO OFF
SETLOCAL
FOR /f "delims==" %%i IN ('set $ 2^>nul') DO SET "%%i="
FOR /f "delims=" %%i IN ('wmic process get Name^, ProcessId^, WorkingSetSize ') DO (
 IF DEFINED $0 (
  SET wss=%%i
  CALL SET wss=0000000000000000000%%wss:~60%%
  CALL SET wss=%%wss: =%%
  CALL SET wss=$%%wss:~-20%%
  CALL SET %%wss%%=%%i
 ) ELSE (SET $0=%%i)
)

FOR /f "tokens=1*delims==" %%i IN ('set $') DO ECHO(%%j

This should do your sort.

The sticking points are: the WMIC command requires commas between fieldnames. These need to be escaped in the for/f

All environment variables starting "$" are first deleted, then each line of WMIC is processed. The first line (the header) is saved in $0 then each line is saved in $size

The trick here is that SIZE in the listing is not only left-justified by space-padded, hence the string of zeroes is first prefixed to the contents of the workingsetsize column which probably actually begins in column 62 - but column 61 is a space. "60" is used since the substring facility counts from column 0, not column 1.
Then each space is replaced by [nothing], stripping out the trailing spaces (also conveniently, the space from col 61)
The last 20 characters from the resultant string form a leading-zero-filled version of the workingsetsize column.
prepend a $ to tha, and set the resultant variable to the contents of the line that generated it

Finally, listing the contents of the $ variables produces the required list in the required order.

Note that the claims that the WMIC process output described is in order whatever is erroneous. Closer examination would reveal that it is not in order of ProcessID - either alphabetically (since that column is also left-justified) or alphabetically.


OK - revised version, should auto-adjust to width of process-name column:

@ECHO OFF
SETLOCAL
FOR /f "delims==" %%i IN ('set $ 2^>nul') DO SET "%%i="
SET /A COUNT=0
FOR /f "delims=" %%i IN ('wmic process get Name^, ProcessId^, WorkingSetSize ') DO (
 IF DEFINED $0 (
  SET wss=%%i
  CALL %%lopcmd%%
  CALL SET wss2=%%wss2: =%%
  SET /A COUNT+=1
  CALL SET wss=$%%wss2:~-20%%%%COUNT%%
  CALL SET %%wss%%=%%i
 ) ELSE (SET $0=%%i&set/a wsscol=0&CALL :findcol&SET $0=%%i)
)
FOR /f "tokens=1*delims==" %%i IN ('set $') DO ECHO(%%j
GOTO :eof

:findcol
IF "%$0:~0,1%"=="W" SET lopcmd=CALL SET wss2=0000000000000000000%%wss:~%wsscol%%%&GOTO :eof
SET $0=%$0:~1%
SET /a wsscol+=1
GOTO findcol

No substantial changes - just calculate the width required by locating the "W" in the header and establishing an appropriate command to set the variable ready for processing...and which has to executed using the CALL %%var%% method...


Minor edit: introducing COUNT to distinguish between lines with identical workingsetsizes. Count is simply extends the variable-name used for sorting and makes the name unique.




回答2:


Is this any use to you? It works in Win 8 to provide a list of processes sorted by memory usage.

tasklist /nh |sort /+65



回答3:


This might work on the command line (depends on Windows version, without any warranty!):

(for /f "delims=" %i in ('wmic process get Name^, ProcessId^, WorkingSetSize ') do @set "wss=%i" &call set "wss=%wss:~0,35%%wss:~-12%"&call echo(%wss%) | more +1 | sort /+35



回答4:


I understand your question and this works just fine for me on Windows 10:

wmic process list  get name, version |sort
or
wmic process list status |sort
or
wmic process list io |sort

Expounding upon Foxidrive's answer, this works with tasklist also:

tasklist /nh | sort

and no need for the /+65 (thanks for that info foxidrive)

"tasklist" on Windows 10 will do this also:

tasklist /nh /fo table
or
tasklist /fo list
or
tasklist /nh |sort



回答5:


I used Peter's technique here but returned the data in CSV format, which is easier to parse for a batch file in "PID, WorkingSetSize, Name" format sorted on the size column.

@ECHO OFF
SETLOCAL
FOR /f "delims==" %%i IN ('set $ 2^>nul') DO SET "%%i="
FOR /f "skip=2 tokens=2-4 delims=," %%a IN ('cmd /c "wmic process get Name, ProcessId, WorkingSetSize /format:csv" ') DO (

  SET wss=0000000000000000000%%c
  CALL SET $%%wss:~-20%%=%%b,%%c,%%a

)

FOR /f "tokens=1*delims==" %%i IN ('set $') DO ECHO(%%j
pause


来源:https://stackoverflow.com/questions/16578513/can-a-wmic-processes-table-within-the-command-prompt-window-be-sorted-by-a-val

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!