Is there any way to remove the entries with same process names? - windows

I'm trying to get the top 10 memory consuming processes and I am using the code provided as an answer in this Question. It works fine except that I don't want multiple entries of processes consuming different memory size and I was unable to sort it because it's memory consumption is different.
The code is:
#echo off
setlocal EnableDelayedExpansion
(for /F "skip=1 tokens=1,2" %%a in ('wmic process get name^,workingsetsize') do (
set "size= %%b"
echo !size:~-10!:%%a
)) > wmicc.txt
set i=0
for /F "skip=1 delims=" %%a in ('sort /R wmicc.txt') do (
echo %%a
set /A i+=1
if !i! equ 25 goto :end
)
:end
Can I get the output as:
96931840:iexplore.exe
82161664:explorer.exe
42319872:svchost.exe
31469568:dwm.exe
25690112:SearchIndexer.exe
17002496:taskhostex.exe
11007590:VCExpress.exe
8033894:avp.exe
7190528 :Skype.exe
7000416 :SkypeBrowserHost.exe
Instead of the output from existing code:
96931840:iexplore.exe
82161664:explorer.exe
42319872:svchost.exe
33656832:svchost.exe
31469568:dwm.exe
26943488:iexplore.exe
25690112:SearchIndexer.exe
18550784:svchost.exe
17002496:taskhostex.exe
16343040:svchost.exe

#echo off
setlocal EnableDelayedExpansion
set num=25
set /A skip=-num
for /F "skip=1 tokens=1,2" %%a in ('wmic process get name^,workingsetsize') do (
set "size= %%b"
set "size=!size:~-10!"
if not defined proc[%%a] (
set "proc[%%a]=!size!"
set "size[!size!:%%a]=1"
set /A skip+=1
) else if %%b gtr !proc[%%a]! (
set "size[!proc[%%a]!:%%a]="
set "proc[%%a]=!size!"
set "size[!size!:%%a]=1"
)
)
if %skip% lss 1 (set "skip=") else set "skip=skip=%skip%"
for /F "%skip% tokens=2 delims=[]" %%a in ('set size[') do echo %%a
Output example:
5517312:NisSrv.exe
5537792:HD-LogRotatorService.exe
5939200:spoolsv.exe
6062080:WUDFHost.exe
6168576:igfxpers.exe
6279168:conhost.exe
6369280:wmpnetwk.exe
6533120:hkcmd.exe
6692864:igfxtray.exe
8073216:notepad.exe
8077312:WMIC.exe
8105984:taskhost.exe
9306112:lsass.exe
11157504:winlogon.exe
11767808:taskhostex.exe
13402112:SkyDrive.exe
16629760:TabTip.exe
17121280:SearchIndexer.exe
26120192:HD-Agent.exe
32325632:csrss.exe
36429824:svchost.exe
43114496:dwm.exe
101998592:explorer.exe
110260224:MsMpEng.exe
114425856:chrome.exe

#echo off
setlocal EnableDelayedExpansion
for /f "delims==" %%a in ('set # 2^>nul') do set "%%a="
(for /F "skip=1 tokens=1,2" %%a in ('wmic process get name^,workingsetsize') do (
set "size= %%b"
echo !size:~-10!:%%a
)) > wmicc.txt
set i=0
for /F "skip=1 delims=" %%a in ('sort /R wmicc.txt') do (
for /f "tokens=1*" %%p in ("%%a") do (
rem the following line doesn't work
rem if not defined "#%%q"
rem the preceding line doesn't work
SET "flag="
FOR /f "tokens=1*delims==" %%v IN ('set #%%q 2^>nul') DO IF /i "%%v"=="#%%q" SET "flag=Y"
IF NOT DEFINED flag (
set "#%%q=Y"
echo %%a
set /A i+=1
if !i! equ 25 goto :end
)
)
)
:end
This tokenises the entire line as read into %%p,q so %%q contains the process-name. It then checks whether the variable #processname is defined and if it is not, generates the report-line and sets #processname so that the first mention will be the last as that variable is now defined.
The first line is designed to set any existing #* variables to empty; the 2^>nul suppresses error messages should no #* variables exist and the caret escapes the > to tell cmd that the > is part of the command to be executed, not of the for.
[later]
It appears that the if defined "varname" that I invented doesn't actually work, although it appeared to work when I tested it. I've replaced that instruction with code that does work and marked it out.

Related

Batch variable store result from command

It seems for me a very simple question, however I am struggling a lot with this and don't find an answer yet.
My aim is to count occurences of a specific string in a file.
I do or try to do this using following command:
for /f "tokens=2 delims=;" %%a in ('path to file with searchstring') do (
set count=('path to file I am searching in' find /c "%%a")
if !count! NEQ 0 echo !count!
)
Seems straightforward for me however the second line seems to be wrong as the script exits.
I want to save the result of findin a var because I only wants to outpout Nonzero resutls.
Here's an example batch-file using findstr, for better word matching, (It uses the filenames from your previous question):
#(For /F "UseBackQTokens=2Delims=;" %%G In ("classID.txt")Do #(Set "count=0"
For /F %%H In ('^""%__AppDir__%findstr.exe" /IN "\<%%G\>" "trc.txt"^"'
)Do #(Set /A count+=1)&SetLocal EnableDelayedExpansion
If !count! Gtr 0 (Echo %%G: !count!)&Endlocal))&Pause
Here it is fully parenthesized over multiple lines for you to better understand:
#Echo Off
For /F "UseBackQ Tokens=2 Delims=;" %%G In (
"classID.txt"
) Do (
Set "count=0"
For /F %%H In (
'^""%__AppDir__%findstr.exe" /I /N "\<%%G\>" "trc.txt"^"'
) Do (
Set /A count +=1
)
SetLocal EnableDelayedExpansion
If !count! Gtr 0 (
Echo %%G: !count!
)
Endlocal
)
Pause
And a fully parenthesized example of it outputting the results to a file named results.txt:
#Echo Off
(
For /F "UseBackQ Tokens=2 Delims=;" %%G In (
"classID.txt"
) Do (
Set "count=0"
For /F %%H In (
'^""%__AppDir__%findstr.exe" /IN "\<%%G\>" "trc.txt"^"'
) Do (
Set /A count +=1
)
SetLocal EnableDelayedExpansion
If !count! Gtr 0 (
Echo %%G: !count!
)
Endlocal
)
)>"results.txt"

How to remove names from a list in batch

I'm using windows bath, I have a list of names that I can add to but I don't know how to remove a name from the list.
So far my code is:
#echo off
setlocal enabledelayedexpansion
set allchoices=123456789
set "names=Bob,Steven,Harry"
set amount=6 ::max limit of list
set list=0
:start
::echoes a list of all names in the list
for /l %%i in (1; 1; %amount%) do (
call :sub %%i
)
goto check
:sub
for /f "tokens=%1 delims=," %%a in ("%names%") do (
echo %%i. %%a
set /a list=list+1
)
goto :eof
:check
::Remove a name from the list
choice /c !allchoices:~0,%list%! /m "What name do you want to remove?"
if errorlevel 3 (
for /f "tokens=3 delims=," %%a in ("%names%") do (
echo you have choosen to remove %%a
::remove third name in the list
goto start
)
)
if errorlevel 2 ::remove second name in the list
if errorlevel 1 ::remove first name in the list
I've tried using del but that turns out to delete a file in your folder.
I've tried renaming a specific name using set name[%%a]="" but that did nothing.
Any ideas?
Have a look at this example. There are many ways.
#echo off
setlocal enabledelayedexpansion
set names="Bob","Steven","Harry"
for %%i in (%names%) do (
set /a num+=1
set "!num!=%%~i"
)
for /l %%a in (1,1,%num%) do (
set choices=!choices!%%a
echo !num!.!%%a!
)
choice /c 123 /m "please select name to remove"
for /l %%a in (1,1,%num%) do if not "!%%a!"=="!%errorlevel%!" set new_names=!new_names! !%%~a!
echo %new_names:~1%
It can be done without the last for loop as well.. but I opted for it.
Here is some example code, for you to run, and then try to comprehend, I hope it helps rather than confuses:
#Echo Off
SetLocal EnableDelayedExpansion
For /F "Delims==" %%A In ('Set # 2^>NUL') Do Set "%%A="
Set "i=0"
For /F "Delims=:" %%A In ('FindStr "^::" "%~f0" 2^>NUL') Do (
Set /A i+=1
Set "#!i!=%%A"
Echo= !i!. %%A
)
:Ask
Set # 1>NUL 2>&1
If ErrorLevel 1 Echo= Empty names list&Timeout 3 1>NUL&Exit /B
Echo=&Set /P "Option= Choose a name to remove>"
Set #|Findstr "^#%Option%=" 1>NUL||GoTo :Ask
Set "Name=!#%Option%!"
Echo= You've chosen to remove "%Name%"
Timeout 2 1>NUL
Set "#%Option%="
ClS
For /F "Tokens=1*Delims=#=" %%A In ('Set # 2^>NUL') Do Echo= %%A. %%B
GoTo Ask
::Alan
::Beth
::Cleo
::Dale
::Eric
::Faye
::Greg
::Hugh
::Inga
Important note:Please ensure, before saving the above content as a Windows Command Script, that there is a line return, (blank line), at the end.

How to create a unique output filename for Windows Script?

I am trying to create a windows script that should generate this kind of filename everytime I run it: filename1, filename2, filename3 and so on. Here is what I have so far:
(
#echo off
wmic logicaldisk get size,freespace,caption
) > disk.txt
I hope you can help me. Thanks!!
:: make a tempfile
:maketemp
SET "tempfile=%temp%\%random%"
IF EXIST "%tempfile%*" (GOTO maketemp) ELSE (ECHO.>"%tempfile%a")
You now have any number of filenames available.
%tempfile%a exists and is empty, but %tempfile%anythingelse should be available for use.
#ECHO OFF
SETLOCAL
SET "basename=filename"
SET /a outname=0
:genloop
SET /a outname+=1
IF EXIST "%basename% %outname%.txt" GOTO genloop
SET "outname=%basename% %outname%.txt"
ECHO %outname%
GOTO :EOF
Ah - increment the destination filename on each run. This should do that. It's not actually creating a file - you'd need to create the file %outname% each time to have it increment...
(the space between %basename% and %outname% is optional, of course - omit it if desired.)
edited to include .txt
This will give you up to 1000 filenames but you can go higher, up to 2 Billion, but the higher you go the longer the delay will be before it picks a filename.
#echo off
for /L %%a in (1,1,1000) do if not defined filename if not exist "filename%%a.txt" set "filename=filename%%a.txt"
(
wmic logicaldisk get size,freespace,caption
) > "%filename%"
#echo off
setlocal enableextensions
call :getNextFilename "filename*.txt" nextFilename
echo %nextFilename%
echo test > "%nextFilename%"
call :getNextFilename "%cd%\filename*.txt" nextFilename
echo %nextFilename%
echo test > "%nextFilename%"
endlocal
exit /b
:getNextFilename whatToSearch returnVariable
setlocal enableextensions enabledelayedexpansion
for /f %%a in ("$\%~1"
) do for /f "tokens=1,* delims=*" %%b in ("%%~nxa"
) do ( set "left=%%b" & set "right=%%c" )
set "max=0"
for %%a in ("%~1"
) do for /f "tokens=1 delims=%left%%right% " %%b in ("%%~nxa"
) do for /f "tokens=* delims=0 " %%c in ("0%%~b"
) do if %%~c geq !max! set /a "max=%%c+1"
endlocal & set "%~2=%~dp1%left%%max%%right%" & exit /b
This should find the next file in sequence independently of the existence of holes in the numeration of the files. A path can be included or omitted. The * will be used as the placeholder for the numeration. BUT this will not work if files or included paths have "problematic" characters.
If the date/time of creation of the file can be considered, then this version can be optimized as
:getNextFilename whatToSearch returnVariable
setlocal enableextensions disabledelayedexpansion
for /f %%a in ("$\%~1"
) do for /f "tokens=1,* delims=*?" %%b in ("%%~nxa"
) do ( set "left=%%b" & set "right=%%c" )
set "max=0"
for /f "delims=" %%a in ('dir /tc /o-d /b "%~1" 2^>nul'
) do for /f "tokens=1 delims=%left%%right% " %%b in ("%%~nxa"
) do for /f "tokens=* delims=0 " %%c in ("0%%~b"
) do set /a "max=%%c+1" & goto done
:done
endlocal & set "%~2=%~dp1%left%%max%%right%" & exit /b
that will take the latest created instance of the file set.
I finally figured out where to put the .txt extension. This is from #Magoo's answer but I wanted the file to be a text file so I placed the .txt twice in order for it to work properly.
#ECHO OFF
SETLOCAL
SET "basename=DISK-OUT"
SET /a outname=0
:genloop
SET /a outname+=1
IF EXIST "%basename% %outname%.txt" GOTO genloop
SET "outname=%basename% %outname%.txt"
(
wmic logicaldisk get size,freespace,caption
) > "%outname%"
GOTO :EOF

Read content of files and check if values are same

I have one file located at C:\Users\abc\Desktop named BUIBNESSDATE.
File contents are
Updated on :
Thu Jan 23 04:05:00 IST 2014
ProfileBusinessDate=23/1/2014
NucleusBusinessDate=23/01/2014
I want script which will check if both have same date(ProfileBusi nessDate & NucleusBusinessDate )date are same. If both date are same then script should give message as OK else NotOk.
how to do?
Test this:
#echo off
set "file=C:\Users\abc\Desktop\BUIBNESSDATE"
for /f "tokens=2 delims==" %%a in (' find /i "profile" ^< "%file%" ' ) do set "p=%%a"
for /f "tokens=2 delims==" %%a in (' find /i "nucleus" ^< "%file%" ' ) do set "n=%%a"
if "%p%"=="%n%" (echo OK) else (echo NotOK)
#ECHO OFF
SETLOCAL
SET "ppd="
SET "nbd="
FOR /f "delims=" %%a IN (q21312106.txt) DO (
SET "line=%%a"
CALL :process
)
IF NOT DEFINED ppd ECHO ProfileBusinessDate missing&GOTO :EOF
IF NOT DEFINED nbd ECHO NucleusBusinessDate missing&GOTO :EOF
FOR /f "tokens=1-3delims=/" %%a IN ("%ppd%") DO CALL :slz ppdd %%a&CALL :slz ppdm %%b&CALL :slz ppdy %%c
FOR /f "tokens=1-3delims=/" %%a IN ("%nbd%") DO CALL :slz nbdd %%a&CALL :slz nbdm %%b&CALL :slz nbdy %%c
IF "%ppdd%-%ppdm%-%ppdy%"=="%nbdd%-%nbdm%-%nbdy%" (ECHO OK) ELSE (ECHO NotOk)
GOTO :EOF
:process
SET "$1=%line:*ProfileBusinessDate=%"
IF NOT "%$1%"=="%line%" SET "ppd=%$1:~1%"&GOTO :EOF
SET "$1=%line:*NucleusBusinessDate=%"
IF NOT "%$1%"=="%line%" SET "nbd=%$1:~1%"&GOTO :EOF
GOTO :EOF
:: suppress a leading 0
:slz
SET "$1=%2"
IF "%$1:~0,1%"=="0" (SET "%1=%$1:~1%") ELSE (SET "%1=%2")
GOTO :eof
Should do the task. I used q21312106.txt with your data as a source file.
#echo off
setlocal enableextension disabledelayedexpansion
set "pdb="
set "nbd="
for /f "tokens=1,2 delims==" %%a in (
'findstr /b /l /c:"ProfileBusinessDate=" /c:"NucleusBusinessDate=" "c:\users\abc\desktop\buibnessdate"'
) do (
if "%%a"=="ProfileBusinessDate" (set "pbd=%%b" ) else (set "nbd=%%b")
)
if "%pdb%"=="%nbd%" (
echo OK
) else (
echo NOT OK
)
Search the file for the required lines, splitting them on equal sign and assigning the values to the adecuated variables. Then check if both variables hold the same content.

set nor working inside a for loop for windows dos cmd

I have a script that eill search for certain directories and set a list of paths for the given directories, now i want to exclude from them some recurrent unwanted ones.
Here's the script
#ECHO off
setlocal enableextensions
:start
set scriptname=%0%
set PAUSE_ON_ERROR=yes
rem #
rem ###### SECTION TO CUSTOMIZE #####
rem #
rem #
rem # This is the list of directories where instances of TECSYS iTopia installed under
rem # JBoss are located.
rem #
set jboss_dir_list=C: C:\TecsysDev\iTopiaControlPanel\trunk
rem #
rem ###### END SECTION TO CUSTOMIZE #####
rem #
set argNb=0
for %%x in (%*) do Set /A argNb+=1
if %argNb% GTR 1 (
goto :showUsage
) else if %argNb% == 0 (
set ENV_NAME=*
) else (
set ENV_NAME=*%~1*
)
:MainBlock
set scriptname=%0%
cd /d %~dp0
for /f "usebackq delims=" %%D in (`cd`) do set scriptdir=%%D
for /f "usebackq delims=" %%D in (`cd`) do set CURRENT_DIR=%%D
cd "%scriptdir%"
for /f "usebackq delims=" %%D in (`cd`) do set JBOSS_DIR=%%D
set JBOSS_DIR=%JBOSS_DIR%\..\..\..\..\..
cd "%JBOSS_DIR%"
for /f "usebackq delims=" %%D in (`cd`) do set JBOSS_DIR=%%D
cd "%CURRENT_DIR%"
rem Make sure that we have the findstr utility installed.
set findstr_found=
for /f "usebackq" %%f in (`echo x ^| findstr x 2^>nul`) do set findstr_found=%%f
if "X%findstr_found%" == "X" (
echo The findstr utility is not found.
goto pauseforError
)
call :getJbossVersion
rem prepare the list of special JBoss environments to exclude
if /i "%JBOSS_VERSION%" lss "5" (
set env_to_exclude=all default minimal
) else if /i "%JBOSS_VERSION%" lss "6" (
set env_to_exclude=all default minimal standard web
) else (
set env_to_exclude=all default minimal jbossweb-standalone standard
)
rem find the environment directories
setlocal enabledelayedexpansion
Set Count=1
for %%f in (%jboss_dir_list%) do (
for /f "delims=" %%G in ('dir /b /ad "%%~f\jboss*"') do (
if exist "%%f\%%G\server\%ENV_NAME%" (
for /f "delims=" %%H in ('dir /b /ad "%%~f\%%~G\server\%ENV_NAME%"') do (
echo count est !count!
call :concat %%~f\%%~G\server\%%~H
Set /A Count+=1
)
)
)
)
rem echo %ENV_NAME%
rem %jboss_home_list%
:concat
echo the environment is %1
set is_env_to_exclude=no
for %%L in (%env_to_exclude%) do (
set is_env_to_exclude=no
for /f "usebackq delims=" %%U in (`echo %1 ^| findstr %%L`) do (
set is_env_to_exclude=yes
echo flag du Ellouze
)
)
echo %is_env_to_exclude%
rem echo %is_env_to_exclude%
rem set jboss_home_list=%1 %jboss_home_list%
goto :eof
:getJbossVersion
for /f "usebackq tokens=2" %%v in (`echo. ^| %JBOSS_DIR%\bin\run.bat -V ^| ^
findstr "JBoss" ^| findstr /i /v "BootStrap"`) do (
set JBOSS_VERSION=%%v
)
goto :EOF
:showUsage
echo Usage: tish [environment]
echo ^|
echo +--- installed environment
rem SET /P uname=Please enter your name:
rem IF "%uname%"=="" GOTO Error
rem ECHO Hello %uname%, Welcome to DOS inputs!
rem GOTO End
rem :Error
rem ECHO You did not enter your name! Bye bye!!
:pauseforError
if "%PAUSE_ON_ERROR%" == "yes" pause
:End
My idea is to to do the filetring through the :concat subroutine, problem is set is_env_to_exclude=yes insrtuction inside the for loop isn't working, when i execute the script the echo flag is displaying but the set is_env_to_exclude is always set to no.
I think what you need is to break the loop:
echo the environment is %1
set is_env_to_exclude=no
for %%L in (%env_to_exclude%) do (
set is_env_to_exclude=no
for /f "usebackq delims=" %%U in (`echo %1 ^| findstr %%L`) do (
set is_env_to_exclude=yes
echo flag du Ellouze
goto :break_loop
)
)
:break_loop
echo %is_env_to_exclude%
as on each iteration over %env_to_exclude% items the is_env_to_exclude is set to no.
Although the code is a little bit complicated for me :)
It really depends on the contents of env_to_exclude.
is_env_to_exclude will be set to no for each %%L, so even if it is set to yes once, if there are more elements processed after it's been set, it will be re-set to no.
The
set is_env_to_exclude=no
in the loop seems to be the culprit; removing it would seem to fix the problem.
AAMOI, set "flag=" and set flag=Y allows if [not] defined flag which has the added advantage that the CURRENT status of the flag is available within a FOR loop without needing enabledelayedexpansion.

Resources