Count number of files in zip archive

Microsoft Windows xp professional editio...
November 4, 2009 at 14:44:18
Specs: Windows XP
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%                                            2

The 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 better

I 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 how

        0                   2 files
need to be come

2 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


See More: Count number of files in zip archive

Report •


#1
November 4, 2009 at 18:01:14
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%


Report •

#2
November 4, 2009 at 18:44:12
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


Report •

#3
November 4, 2009 at 19:04:20
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


Report •

Related Solutions

#4
November 5, 2009 at 01:39:39
is there actually a space between the escape ^ and the pipe character? if so, that might be your issue. should read like:
unzip .. ^| find

Report •

#5
November 5, 2009 at 02:30:20
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=%%a

Also, 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.


Report •

#6
November 5, 2009 at 07:10:58
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.zip

Invalid 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 ZipFile

Valid Zipped XML files (not working)

zipcount TEST.ZIP
I am sorry I had a error reading TEST.ZIP Are you sure its a valid ZipFile

Here 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 here

http://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.


Report •

#7
November 5, 2009 at 08:54:19
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%" == "".


Report •

#8
November 5, 2009 at 10:02:49
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


Report •

#9
November 5, 2009 at 10:49:52
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"')


Report •

#10
November 5, 2009 at 14:43:34
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.


Report •

#11
November 5, 2009 at 18:30:17
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%


Report •

#12
November 6, 2009 at 01:08:29
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


Report •

#13
November 6, 2009 at 22:05:10
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.

Report •

#14
November 7, 2009 at 15:38:11
Yes it does, but I presume the OP only wanted to read one file at random, not all of them.

Report •

#15
November 8, 2009 at 08:24:06
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


Report •

#16
November 9, 2009 at 19:32:53
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 :-)


Report •


Ask Question