Marcos Posted February 2, 2012 Share Posted February 2, 2012 (edited) I have .txt file with contents similar to below eg.============================Bus 1 Enclosure 1 Disk 12Capacity: 274845State: UnboundBus 1 Enclosure 1 Disk 13Capacity: 274845State: UnboundBus 1 Enclosure 2 Disk 0Capacity: 274845State: EnabledBus 1 Enclosure 2 Disk 1Capacity: 274845State: EnabledBus 2 Enclosure 3 Disk 0Capacity: 1878379State: UnboundBus 2 Enclosure 3 Disk 1Capacity: 1878379State: EnabledBus 2 Enclosure 3 Disk 2Capacity: 1878379State: UnboundBus 2 Enclosure 3 Disk 9State: EmptyBus 2 Enclosure 3 Disk 10State: Empty==================================I need a batch file to do the below:1. Read thru' the file and search only unbound disks and associated capacity.2. Unique value of capacity and count of each value.For eg. The above data has two unique values of capacity for Unbound Disks -- '274845' & '1878379'.Disk with capacity > 274845 has count 4 & disk with capacity > 1878379 has count 3Note: I may be able to run .vbs as well, but prefer to have a .bat or .cmdThanks Edited February 2, 2012 by Marcos Link to comment Share on other sites More sharing options...
Yzöwl Posted February 2, 2012 Share Posted February 2, 2012 Could you please provide a better explanation, it appears to me as if your count includes disks which are not Unbound.Also it would help if you could provide an example of the output file you're expecting. Link to comment Share on other sites More sharing options...
Marcos Posted February 2, 2012 Author Share Posted February 2, 2012 (edited) Sorry, I seem to have confused self and others with my earlier statements. I need the below:1. No. of Unbound disks and their capacity.2. No. of disks with similar capacity.Output will be something like this for the above example.No. of Unbound disks: 4Count of Unbound disks with size 274845 = 2Count of Unbound disks with size 1878379 = 2 Edited February 2, 2012 by Marcos Link to comment Share on other sites More sharing options...
jaclaz Posted February 2, 2012 Share Posted February 2, 2012 This should do:@ECHO OFFSETLOCAL ENABLEEXTENSIONSSETLOCAL ENABLEDELAYEDEXPANSIONSET Unbound_274845=0SET Unbound_1878379=0FOR /F "tokens=1,2 delims=:" %%A IN ('TYPE "%~dpnx1"') DO (IF "%%A"=="Capacity" SET /A Current=%%BIF "%%B"==" Unbound" SET /A Unbound_!Current!+=1)SET /A Unbound=%Unbound_274845%+%Unbound_1878379%ECHO No. of Unbound disks: %Unbound%ECHO Count of Unbound disks with size 274845 = %Unbound_274845%ECHO Count of Unbound disks with size 1878379 = %Unbound_1878379%jaclaz Link to comment Share on other sites More sharing options...
Yzöwl Posted February 2, 2012 Share Posted February 2, 2012 This should do:<snip />I'm not sure that the intention was to have pre-known the disk capacities. Link to comment Share on other sites More sharing options...
Guest Posted February 2, 2012 Share Posted February 2, 2012 (edited) I agree with Yzöwl.Since batch scripts have no built in functions for creating or manipulating arrays we need to write them ourselves. The following tested script does what you ask, Marcos. In the following example the text file should be named "Disks.txt".@ECHO OFFSETLOCAL EnableDelayedExpansion::Initialize arraySET "aCapacity="SET "aUniqueCapacities="SET /A nArrayDepth_Capacity=0SET /A nArrayDepth_UniqueCapacities=0::Create array of Unbound capacitiesFOR /F "usebackq tokens=1-2" %%G IN ("Disks.txt") DO ( IF /I NOT "%%G %%H"=="State: Unbound" (SET sCapacity=%%H) ELSE ( SET "aCapacity=!aCapacity!!sCapacity! " SET /A nArrayDepth_Capacity+=1) )ECHO No. of Unbound disks: !nArrayDepth_Capacity!::Find unique capacity values (searching an array destroys the array, make a copy)SET "aArrayToSearch=!aCapacity!"FOR /L %%G IN (1,1,!nArrayDepth_Capacity!) DO ( FOR /F "tokens=1" %%H IN ("!aArrayToSearch!") DO ( IF !nArrayDepth_UniqueCapacities! EQU 0 (SET bElementSearch_FuncResult=False) ELSE ( CALL :Func_ElementSearch "%%H" "!aUniqueCapacities!" !nArrayDepth_UniqueCapacities! ) IF /I "!bElementSearch_FuncResult!"=="False" ( SET "aUniqueCapacities=!aUniqueCapacities!%%H " SET /A nArrayDepth_UniqueCapacities+=1 ) CALL :Func_FindStringLength "%%H" SET /A nFindStringLength_FuncResult+=1 FOR /L %%I IN (1,1,!nFindStringLength_FuncResult!) DO (SET aArrayToSearch=!aArrayToSearch:~1!)) )::Count instances of unique capacity valuesFOR /L %%G IN (1,1,!nArrayDepth_UniqueCapacities!) DO ( FOR /F "tokens=1" %%H IN ("!aUniqueCapacities!") DO ( CALL :Func_ElementSearch "%%H" "!aCapacity!" !nArrayDepth_Capacity! ECHO Count of Unbound disks with size %%H = !nElementSearch_FuncResult! CALL :Func_FindStringLength "%%H" SET /A nFindStringLength_FuncResult+=1 FOR /L %%I IN (1,1,!nFindStringLength_FuncResult!) DO (SET aUniqueCapacities=!aUniqueCapacities:~1!)) )PAUSEGOTO :eof:Func_FindStringLength:: %1=String of unknown lengthSET sTestString_FindStringLength=%~1SET /A nFindStringLength_FuncResult=0:StringLengthUnknown_FindStringLengthIF NOT "!sTestString_FindStringLength!"=="" ( SET sTestString_FindStringLength=!sTestString_FindStringLength:~1! SET /A nFindStringLength_FuncResult+=1 GOTO :StringLengthUnknown_FindStringLength)GOTO :eof:Func_ElementSearch:: %1=Element to find, %2=String array, %3=Depth of arraySET "aStringArray_ElementSearch=%~2"SET "bElementSearch_FuncResult=False"SET /A nElementSearch_FuncResult=0FOR /L %%Q IN (1,1,%3) DO ( FOR /F "tokens=1" %%R IN ("!aStringArray_ElementSearch!") DO ( IF "%%R"=="%~1" ( SET bElementSearch_FuncResult=True SET /A nElementSearch_FuncResult+=1 ) CALL :Func_FindStringLength "%%R" SET /A nFindStringLength_FuncResult+=1 FOR /L %%S IN (1,1,!nFindStringLength_FuncResult!) DO (SET aStringArray_ElementSearch=!aStringArray_ElementSearch:~1!)) )GOTO :eof Edited February 2, 2012 by 5eraph Link to comment Share on other sites More sharing options...
jaclaz Posted February 2, 2012 Share Posted February 2, 2012 I'm not sure that the intention was to have pre-known the disk capacities.Neither am I. The posted example was the simplest possible covering OP requests as they were explicited (or at least as I understood them).If you have n different disk sizes, the example can be easily made "self-learning".New example:@ECHO OFFSETLOCAL ENABLEEXTENSIONSSETLOCAL ENABLEDELAYEDEXPANSIONFOR /F "tokens=1,2 delims=:" %%A IN ('TYPE "%~dpnx1"') DO (IF "%%A"=="Capacity" SET /A Current=%%BIF "%%B"==" Unbound" SET /A Unbound_!Current!+=1)FOR /F "tokens=2 delims==" %%A IN ('SET Unbound_') DO SET /A Unbound_=!Unbound_!+%%AECHO No. of Unbound disks: %Unbound_%FOR /F "Skip=1 tokens=1,2,3 delims=_=" %%A IN ('SET Unbound_') DO ECHO Count of Unbound disks with size %%B = !Unbound_%%B!The batch does not check existance of any previous "Unbound_*" variable in the environment, but this can be added as a "safety/sanity" check.SET Unbound_=FOR /F "tokens=2 delims=_=" %%A IN ('SET Unbound_') DO SET Unbound_%%A=jaclaz Link to comment Share on other sites More sharing options...
Guest Posted February 2, 2012 Share Posted February 2, 2012 I hadn't thought of using variables that way, jaclaz, and didn't know it could be done (setting a variable name using another variable). I mainly repurposed code I've been working with recently. Link to comment Share on other sites More sharing options...
jaclaz Posted February 2, 2012 Share Posted February 2, 2012 I hadn't thought of using variables that way, jaclaz, and didn't know it could be done (setting a variable name using another variable). Yep that was supposed to be the clever part .I mainly repurposed code I've been working with recently.Yes, and definitely your snippet is a much better solution for "generic" arrays, but within the limits of OP needs, I find that the fun in the game is to find the simplest possible answer:http://en.wikipedia.org/wiki/Occam's_razorjaclaz Link to comment Share on other sites More sharing options...
Marcos Posted February 2, 2012 Author Share Posted February 2, 2012 (edited) Thanks a lot Guys !!! Never knew it's such an AWESOME Forum !!!Let me try the codes and see if it does the trick ! Will get back if I have any problems !I suppose I can't 'challenge-enough' U guys with any 'This-is-too-hard-to-batch' problems ! Edited February 2, 2012 by Marcos Link to comment Share on other sites More sharing options...
Marcos Posted February 2, 2012 Author Share Posted February 2, 2012 This one's for Jaclaz...What does this do ('TYPE "%~dpnx1"') in the batch example ? Read from a file ? Do I need to replace something ? Sorry if it's a stupid question ! Link to comment Share on other sites More sharing options...
Yzöwl Posted February 2, 2012 Share Posted February 2, 2012 The command is typing the content of a given parameter, the parameter is intended to be your .txt file. drive:\path\name.extensionThe following are two methods of running the batch file with the given parameter:drag and drop the .txt file onto the batch fileenter the following into a command prompt X:\pathto\batchfile.cmd M:\pathto\textfile.txtAlternatively replace:FOR /F "tokens=1,2 delims=:" %%A IN ('TYPE "%~dpnx1"') DO (withFOR /F "usebackq tokens=1-2 delims=:" %%A IN ("M:\pathto\textfile.txt") DO ( Link to comment Share on other sites More sharing options...
jaclaz Posted February 2, 2012 Share Posted February 2, 2012 This one's for Jaclaz...What does this do ('TYPE "%~dpnx1"') in the batch example ? Read from a file ? Do I need to replace something ? Sorry if it's a stupid question !No, that is parameter %1 to the batch, normally the filename you wish to process.Example:You have saved the batch as countunbound.cmd and you have the list in a file that is called mylist.txt, this latter in C:\mylists\You then invoke the batch like:countunbound.cmd mylist.txtprovided that you open a command prompt in the same directory where BOTH files are (C:\mylists\).Or:C:\mybatches\countunbound.cmd mylist.txtif the prompt is in the same directory where mylist.txt and it is not the same as the one countunbound.cmd is (C:\mybatches\)Or:countunbound.cmd C:\mylists\mylist.txtif the prompt is in the directory where countunbound.cmd is and mylist.txt is in directory C:\mylists\."%~dpnx1"will expand in all cases to "C:\mylists\mylist.txt"see here also:With this approach you should also be able to use drag 'n drop, just add a PAUSE at the end of the batch.jaclaz Link to comment Share on other sites More sharing options...
Yzöwl Posted February 2, 2012 Share Posted February 2, 2012 I know that the question has been well and truly answered, but I had a few minutes to spare and decided to play around.Here is the resulting script, it uses ideas from that which I've seen above.@echo off & setlocal enableextensions enabledelayedexpansion(set _t=m:\pathto\textfile.txt) & (set _s=unbound)set "_u=!_s!_disks" & set "_z=!_u!_with_size" & set "!_u!=0"for /f "delims=:" %%f in ('findstr/nil "!_s!" "%_t%"') do ( set "_=%%f" & set/a "!_u!+=1" & set/a "_-=1" for /f "tokens=3 delims=: " %%c in ( 'findstr/n .* "%_t%"^|findstr "^^!_!:"') do ( if not defined !_z!_%%c (set "!_z!_%%c=1") else (set/a "!_z!_%%c+=1")) set "_=")for /f %%a in ('set %_u%') do set "_=%%a" & echo=!_:_= !The end user needs only to set the two variables on line two, i.e. the text file (M:\PathTo\TextFile.txt), the drive state (unbound | enabled)Please bear in mind that this script is not intended as a better solution than what has gone before, it was done purely for the purpose of interest and because I'm back on a Windows PC today. Link to comment Share on other sites More sharing options...
jaclaz Posted February 3, 2012 Share Posted February 3, 2012 (edited) And, at the ONLY scope of showing what the idea behind Occam's Razor is, I tried the various batches timing them on the sample file posted, which I saved as "unbound.txt".Results (in a x10 loop):the second one posted by me (with "unbound.txt" hardcoded) takes around 30/100th in a x10 loop.the one by 5eraph is not working ( it just shows the total number of unbound disks, than hangs) @5eraph, can you check it? (maybe is one of those pesky copy/paste from board) updated, see below, it runs in around 80/100the one posted by Yzöwl takes around 1 seconds and 80/100 the following one (in which I took the liberty of inverting the order of the output in order to remove a FOR loop) takes around 16/100th@ECHO OFFSETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSIONFOR /F "tokens=1,2 delims=:" %%A IN (unbound.txt) DO (IF "%%A"=="Capacity" SET /A Current=%%BIF "%%B"==" Unbound" SET /A Unbound_!Current!+=1)FOR /F "tokens=1,2,3 delims=_=" %%A IN ('SET Unbound_') DO (ECHO Count of Unbound disks with size %%B = !Unbound_%%B!SET /A Unbound_=!Unbound_!+%%C)ECHO No. of Unbound disks: %Unbound_%jaclaz Edited February 3, 2012 by jaclaz Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now