Tom's Guide | Tom's Hardware | Tom's Games
![]() |
![]() |
![]() |
I was trying to see if there is a method to count the number of files in a zip archive with out extracting it.
I had a look at winzip's command line interface and there is a command for it but.
wzunzip -vm test.zip WinZip(R) Command Line Support Add-On Version 3.1 (Build 8519) Copyright (c) 1991-2009 WinZip International LLC - All Rights Reserved Zip file: test.zip Length Method Size Ratio Date Time CRC-32 Attr Name ------------ ------ ------------ ----- ---- ---- -------- ---- ---- 0 Stored 0 0% 05/11/2009 09:31 00000000 --w- helloworld.txt 0 Stored 0 0% 05/11/2009 09:31 00000000 --w- helloworld2.txt ------------ ------------ --- --------- 0 0 0% 2The number of files was hard for me to count
I found UnZip 5.52 of 28 February 2005, by Info-ZIP
Archive: test.zip
Length Date Time Name
-------- ---- ---- ----
0 05/11/09 09:31 helloworld.txt
0 05/11/09 09:31 helloworld2.txt
-------- -------
0 2 files
And that was a little betterI was able to use
unzip -l test|find "files"
0 2 files
Do you think there is a better method or to try and use some thing stronger than a batch file also need to clean up the output some how0 2 filesneed to be come2 files
The 0 is the zip size in the above example the files in the zip file are 0k so this will change so can't match it each time.Any ideas

I don't think piping it to find "files" will work. There may be a
file in the zip archive called "files".This gets the second word from the last line, which is the
number of files:setlocal
for /f "tokens=2" %%a in ('unzip -l test') do set nfiles=%%a
echo Number of files: %nfiles%

Good Points
This is what I have come up with so far, One very handy part of my problem is the zip files will always hold XML files.
But I need to populate %FIND RESULTS% with the results of find.
@ECHO OFF set ERRORLEVEL= IF %1.==. GOTO NOZIP unzip -l %1| FIND /C /I "XML" > Nul if %ERRORLEVEL% EQU 0 ( GOTO ZiPRESULT ) else ( GOTO ZIPERROR ) :ZiPRESULT Echo There where %FIND RESULTS% XML files in %1 GOTO EXIT :ZIPERROR ECHO. ECHO I am sorry I had a error reading %1 Are you sure its a valid ZipFile GOTO EXIT :NOZIP ECHO. Echo No Zipfile Specified! ECHO. ECHO Example Useage: ECHO. Echo %0 Zipfile.zip GOTO EXIT :EXIT set ERRORLEVEL= ECho Exiting

I tried to use for FOR example to extract the result but can not see to get it to work
@ECHO OFF setlocal set ERRORLEVEL= set MyVar= IF %1.==. GOTO NOZIP for /f "tokens=2" %%a in ('unzip -l %1 ˆ|FIND /C /I ".XML"') do set MyVar=%%a if %ERRORLEVEL% EQU 0 ( GOTO ZiPRESULT ) else ( GOTO ZIPERROR ) :ZiPRESULT Echo There where %MyVar% XML files in %1 GOTO EXIT :ZIPERROR ECHO. ECHO I am sorry I had a error reading %1 Are you sure its a valid ZipFile GOTO EXIT :NOZIP ECHO. Echo No Zipfile Specified! ECHO. ECHO Example Useage: ECHO. Echo %0 Zipfile.zip GOTO EXIT :EXIT set ERRORLEVEL= ECho Exiting
Error| was unexpected at this time

is there actually a space between the escape ^ and the pipe character? if so, that might be your issue. should read like:
unzip .. ^| find

The reason you get the error is that you are not using a caret (^) but some other obscure character instead (ˆ) - whatever that character is, it's not on my keyboard, so I don't know where you found it.
Also, my FOR /F statement was designed to work only with exactly the command that I gave inside the brackets. If you're going to find to count the number of lines then don't tell it to use the second token, there's only one token in the output:
for /f %%a in ('unzip -l %1 ^|FIND /C /I ".XML"') do set MyVar=%%aAlso, you shouldn't need to handle ERRORLEVEL as an environment variable. For simplicity, remove the two SET ERRORLEVEL= statements and use this built-in statement instead:
IF NOT ERRORLEVEL 1 ( GOTO ZiPRESULT ) else ( GOTO ZIPERROR )Actually, I don't like GOTOs - you can just put your statements inside the IF/ELSE blocks instead of GOTOs.

Thanks for the replies guys I have fixed up the code with the ideas and cleaned it up,
but have an issue with the errorlevel now not sure if I am getting the error level back from the "FOR command" When I pass a valid zip file I get a errorlevel 1 meaning invalid zip file/or problem running the find command
No Zip file past (Working)
zipcount No Zipfile Specified! Example Useage: zipcount Zipfile.zipInvalid Zip file (Working)
zipcount HELLO unzip: cannot find either HELLO or HELLO.zip. I am sorry I had a error reading HELLO Are you sure its a valid ZipFileValid Zipped XML files (not working)
zipcount TEST.ZIP I am sorry I had a error reading TEST.ZIP Are you sure its a valid ZipFileHere is the code in a debug state where I echo out some of the values.
zipcount TEST.ZIP Current error level is 1 I am sorry I had a error reading TEST.ZIP Are you sure its a valid ZipFile ZIP count is , Current error level is 1
@ECHO OFF setlocal set MyVar= IF %1.==. ( ECHO. Echo No Zipfile Specified! ECHO. ECHO Example Useage: ECHO. Echo %0 Zipfile.zip ECHO. GOTO :eof ) ELSE ( for /f %%a in ('unzip -l %1 ^|FIND /C /I ".XML"') do set MyVar=%%a echo Current error level is %ERRORLEVEL% IF NOT ERRORLEVEL 1 ( Echo There where %MyVar% XML files in %1 GOTO :eof ) else ( ECHO. ECHO I am sorry I had a error reading %1 Are you sure its a valid ZipFile ZIP count is %MyVar% , Current error level is %ERRORLEVEL% GOTO :eof ) )
Here is a copy of the zip file test files and unzip.exe as I am not sure if some times the syntax gets screwed when putting it herehttp://rapidshare.com/files/3027708...
When I remove the Echo statement I see the MyVar set to the correct value of FIND,
Looking at the find errorlevels I was expecting to get a errorlevel of 0 (as in the past code)
0 The search was completed successfully and at least one match was found.1 The search was completed successfully, but no matches were found.
2 The search was not completed successfully. In this case, an error
occurred, and FIND cannot report whether any matches were found.

I'm not sure why it's returning an errorcode of 1. One thing I've just found from testing is that if you have a piped statement:
command1 | command2
then the errorlevel relates to command2 only, no matter what the errorlevel of command1 was.
However, when you put all of that inside a FOR /F loop, I'm not sure what happens.
At least, you can use %MyVar% which has the correct value. As a workaround, instead of checking errorlevel you can do IF "%MyVar%" == "".

Thanks klint for your work around, I found that when the MyVar was in a for statement I could not pull it out with %MyVar% and had to use !Myvar! even though it was getting set correctly.
I then found out that when using this work around the line count would come back as 0 if there where no lines so I used a quick "greater than" check
Let me know what you think
@ECHO OFF setlocal enabledelayedexpansion set MyVar= IF %1.==. ( ECHO. Echo No Zipfile Specified! ECHO. ECHO Example Useage: ECHO. Echo %0 Zipfile.zip Exit /B ) ELSE ( for /f %%a in ('unzip -l %1 ^|FIND /C /I ".XML"') do set MyVar=%%a REM echo Current error level is %ERRORLEVEL% count is !MyVar! IF !MyVar! GEQ 1 ( ECHO. Echo There where !MyVar! XML files in %1 ECHO. Exit /B ) else ( ECHO. ECHO I am sorry I had a error reading %1 Are you sure its a valid ZipFile Exit /B ) )Only issue that I can see is that when you pass a bad zip file name.
I get a response from the unzip command as well I was trying to hide that as the result will get passed to another application any way to hide this
zipcount bob
unzip: cannot find either bob or bob.zip.I am sorry I had a error reading bob Are you sure its a valid ZipFile

I think your IF !MyVar! GEQ 1 sounds reasonable. To suppress the output of unzip, just redirect its standard error output (stderr) to nul:
for /f %%a in ('unzip -l %1 2^>nul ^|FIND /C /I ".XML"')

Thanks klint I had tried piping it to NULL with out any luck but once again your hint got it working :-)
I was thinking of now building on this script as its pretty much working with out any problems.I wanted to try and see if I could view one of the XML files and search for a keyword.
I don't think unzip.exe is able to view a file but I have a feeling winzip command line can so I might try there.

Rough working code, will call this from the main code if we find a XML file
I have to go through all files to find a XML files any XML file will do but as I don't know the names of the file I have to search through all of them maybe there is a better way ?
setlocal for /f "tokens=4" %%a in ('unzip -l test.zip ^|FIND /I ".XML"') do set viewxml=%%a echo Lets view XML file named %viewxml%

If you want to view a file from inside a zip archive without extracting it, you can do this:
unzip -p test.zip %viewxml% | more

doesn't unzip support filespec: unzip -L xx.zip *.xml
for example?
not esp. relevant, since code is working, but might cut down on using "find" and if find is generating error whatever reason, one less ERRORLEVEL to deal with.

If you have an WC command ported for windows, you could just run this:
unzip -l zipfile.zip | wc -l
The output may not be exact, but if you thrown in an additional GREP or FINDSTR you can easily get the exact number of files

Hi Guys thanks for the extra ideas :-) I am pretty happy with the currenty code that we nutted out here, I was able to catch all the bug and errors, (I hope)
I have not had time to site down and write the next part of the code to view the XML file and extract the value of 2 of the elements. but I hope to get round to this later this week ;-)
will post the code and any bugs I found :-)

![]() |
![]() |
![]() |
| Login or Register to Reply | |
| Login | Register |
| Ads by Google |