1. 1
Using the WinZip® Command Line Utility in SAS®
Kenneth W. Borowiak, PPD, Inc.
Michael Kwee, PPD, Inc.
ABSTRACT
A tidy way to send, receive and archive project materials is to put them in a zip file. For ad hoc
tasks, manually adding materials to and extracting from a zip file is not unusual. However, a
‘hands-free’ approach for repetitive zipping and unzipping is desirable. This paper explores using
the WinZip Command Line utility in SAS programs to streamline common tasks.
INTRODUCTION
WinZip is a popular compression software for Windows that is commonly used with its graphical
user interface. For ad hoc tasks, using the GUI to add materials to and extracting from a zip file
is not unusual. However, a ‘hands-free’ approach for repetitive zipping and unzipping is desirable.
The WinZip Command Line Support Add-On provides a command line interface that provides the
ability to use WinZip without the GUI.
This paper will provide a series of examples demonstrating the use of the WinZip Command Line
Utility (WCLU) in SAS code. While calling the WCLU can be accomplished a number ways in SAS
such as the X and %sysexec statements, all examples provided the context of a DATA step using
the SYSTEM call routine1
. The DATA step allows for systematic building of the command when
complications arise from quoting, embedded spaces in paths and filenames and resolving macro
variables.
The examples begin using the files the four RTF files and 5 SAS data sets in the directory
C:NESUG, as shown below in Figure 1. The code to generate the files can be found in the
Appendix at the end of the paper. The examples were tested with WinZip Version 9.0 and WinZip
Command Line Support Add-On 1.0.
1
Using the SYSTEM function to capture the return code from the WCLU call is ideal, but the current set of return codes
are sparse and do not allow for detailed error trapping.
/* Figure 1 – Sample Directory */
2. 2
ZIPPING
The command format for populating a zip file is:
winzip32 action [options] filename.zip files
where:
• winzip32 - Refers to the call to the WinZip executable
• action - The activity being performed, such as adding or moving files into a zip file
• options – Examples of options are adding a password or specifying the compression
method
• filename.zip – Name of the zip file created
• files – The files to be put in the zip file
In our first example, consider adding the AE data set to a zip file with the following DATA step in
Figure 2. The variable ZIPEXE contains the entire path to the WinZip executable, which contains
a space, so it needs to be encapsulated within a pair of double quotes. The field also contains
the –min option, which says to run in a minimized state. When this option is invoked it must
appear as the first option. The –a option says that the file referenced in the FILE variable will be
added to the zip file referenced in the ZIPFILE variable. Note that entire path is included in the
FILE and ZIPFILE variables. The command to be processed is built in CMD variable, which serves
as the input to the SYSTEM call routine.
Examples:
http://support.sas.com/kb/26/011.html /* Example 1 - Add a file to a zip file *
data _null_;
zipexe='"C:Program FilesWinZipWinzip32.exe" -min -a';
zipfile='C:NESUGExample1.zip' ;
file='C:NESUGae.sas7bdat ';
cmd=zipexe || ' ' || zipfile || ' ' || file ;
putlog "NOTE-Processing command" cmd ;
call system( cmd ) ;
run ;
/* Figure 2 - Add a file to a zip file */
data _null_ ;
zipexe='"C:Program FilesWinZipWinZip32.exe" -min -a' ;
zipfile='C:NESUGExample1.zip' ;
file='C:NESUGae.sas7bdat ';
cmd=zipexe || ' ' || zipfile || ' ' || file ;
putlog "NOTE-Processing command " cmd ;
call system( cmd ) ;
run ;
SAS Log:
Processing command "C:Program FilesWinZipWinzip32.exe" -min -a
C:NESUGExample1.zip C:NESUGae.sas7bdat
3. 3
Some of the strings in the first example could have been shortened, as shown in Figure 3. First,
the ZIPEXE fields uses the short file naming convention where only the first characters of a
filepath are displayed followed by ~1. Since the path to the WinZip executable no longer
contains an embedded space it no longer needs to be surrounded by double quotes. Secondly,
since the location of the file to be zipped and the output zip file reside in the same location,
changing the location of the system directory removes the need to explicitly state in the ZIPFILE
and FILE variables.
In the next example, consider moving multiple files (i.e. AE and CM data sets) into a zip file
Example2.zip. The DATA step below looks similar to the one in the first example, but the –a
option is replaced with the –m option and the files to be moved a listed and separated by a
space.
In the next example in Figure 4 multiple data sets are moved to a zip file. The AE and CM data
sets are listed in the FILES field separated by a space and physically moved from their current
location in the NESUG folder to the zip file Example2.zip.
Some other useful features for zipping are demonstrated in Figure 5. The asterisk can be used as
a wildcard, where in the example below it is used to add all files in the NESUG directory to a zip
file. It could also have been used to add all SAS data sets (e.g. *.sas7bdat) or all files that begin
with the letter T (e.g. T* ). A password is also added to secure the zip file with the –s option,
where the actual password directly follows it without a space. Passwords containing a space
should be enclosed with double quotes.
/* Figure 4 - Move multiple files to a zip file */
data _null_ ;
zipexe='"C:Program FilesWinZipWinzip32.exe" -min -m ' ;
zip="C:NESUGExample2.zip" ;
files='C:NESUGae.sas7bdat C:NESUGcm.sas7bdat';
cmd=zipexe || ' ' || zip || ' ' || files ;
putlog "NOTE-Processing command " cmd ;
call system( cmd ) ;
run ;
SAS Log:
Processing command "C:Program FilesWinZipWinzip32.exe" -min -m
C:NESUGExample2.zip C:NESUGae.sas7bdat C:NESUGcm.sas7bdat
/* Figure 3 – Shortening strings in the command */
data _null_ ;
cmd1='cd C:NESUG' ;
putlog "NOTE-Processing command " cmd1 ;
call system( cmd1 ) ;
zipexe='C:Progra~1WinZipWinzip32.exe -min -a' ;
zipfile='Example1B.zip' ;
file='ae.sas7bdat ';
cmd2=zipexe || ' ' || zipfile || ' ' || file ;
putlog "NOTE-Processing command " cmd2 ;
call system( cmd2 ) ;
run ;
4. 4
UNZIPPING
Using the WCLU for unzipping files is similar to zipping, where the main difference is the use of
the –e command for extraction. The other difference is that you need to specify the desired
location of the extracted files. The example below if Figure 6 demonstrates extracting all the files
in the Example2.zip zip file to the NESUG folder.
When unzipping a file to a directory it is possible that a version of that file may already exist, in
which case WinZip will ask you if you want to replace the file. To avoid this manual intervention,
particularly when running your program in batch mode, you can use the –o option to overwrite
any files in conflict without being prompted. This is demonstrated in Figure 7, where a password
is also provided in order to extract just the AE data set from the Example3.zip zip file.
/* Figure 5 - Use a wildcard to add all files in a directory to a zip file */
/* Add a password to the zip file */
data _null_ ;
zipexe='"C:Program FilesWinZipWinzip32.exe" -min -a -s' ;
pw='"myob"' ;
zipfile="C:NESUGExample3.zip" ;
files='C:NESUG*';
cmd=zipexe || pw ||' ' || zipfile || ' ' || files ;
putlog "NOTE-Processing command " cmd ;
call system( cmd ) ;
run ;
SAS Log:
Processing command "C:Program FilesWinZipWinzip32.exe" -min -a -s"myob"
C:NESUGExample3.zip C:NESUG*
/* Figure 6 - Extract all files from a zip file */
data _null_ ;
unzipcmd='"C:Program FilesWinZipWinzip32.exe" -min -e ' ;
zipfile="C:NESUGExample2.zip" ;
whereto='C:NESUG' ;
cmd=unzipcmd || ' ' || zipfile || ' ' || whereto ;
putlog "NOTE-Processing command " cmd ;
call system( cmd ) ;
run ;
SAS Log:
Processing command "C:Program FilesWinZipWinzip32.exe" -min -e
C:NESUGExample2.zip C:NESUG
5. 5
ZIP CONTENTS
You may have the need to extract a list of files contained in a zip file. This can be accomplished
with a FILENAME pipe to call the WZUNZIP executable with the –v option, as demonstrated in
Figure 8. The view option –v is followed by a second option b, for a brief description of the
contents. Information such as the file size and compression ratio is provided for each of the
elements in the zip file. The DATA step FOO can be augmented with steps to extract a list of a
certain type of file (e.g. RTF) using character string functions and call routines, such as PRX.
/* Figure 7 - Extract a file from a zip file */
/* Provide the password */
/* Replace the file if it already exists */
data _null_ ;
unzipcmd='"C:Program FilesWinZipWinzip32.exe" -min -e -o -s' ;
pw="myob" ;
zipfile="C:NESUGExample3.zip" ;
whereto='C:NESUG' ;
file='ae.sas7bdat' ;
cmd=unzipcmd || pw || ' ' || zipfile || ' ' || whereto || ' ' || file ;
putlog "NOTE-Processing command " cmd ;
call system( cmd ) ;
run ;
SAS Log:
Processing command "C:Program FilesWinZipWinzip32.exe" -min -e -o -smyob
C:NESUGExample3.zip C:NESUG ae.sas7bdat
6. 6
CONCLUSION
This paper provided a series of examples to script the addition and extraction of files from a zip
files using the WinZip Command Line Utility. Not all of the functionality and options of the WCLU
were discussed, such as alternative levels of encryption and compression, but the curious reader
should refer to its documentation. Additional examples and related papers can be found in the
References section.
/* Figure 8 - Extracting the contents of a ZIP file */
data _null_ ;
filename="filename foo pipe '" ;
viewzip=' "C:Program FilesWinZipWZUnzip.exe" -vb' ;
zipfile="C:NESUGExample3.zip" ;
fnstmt= filename || ' ' || viewzip || '' || zipfile || "' ;" ;
call execute( fnstmt ) ;
run ;
data foo ;
infile foo truncover ;
input x $300. ;
run ;
Obs x
1 WinZip(R) Command Line Support Add-On Version 1.1 SR-1 (Build 6224)
2 Copyright (c) WinZip Computing, Inc. 1991-2004 - All Rights Reserved
3
4 Zip file: C:NESUGExample3.zip
5
6 Length Size Ratio Date Time Name
7 ------ ----- ----- ---- ---- ----
8 5120 1630 69% 15/08/2010 21:29 ae.sas7bdat
9 5120 1642 68% 15/08/2010 21:29 cm.sas7bdat
10 5120 1131 78% 15/08/2010 21:29 dm.sas7bdat
11 5120 1259 76% 15/08/2010 21:29 ds.sas7bdat
12 5120 827 84% 15/08/2010 21:29 mh.sas7bdat
13 21520 1420 94% 15/08/2010 21:29 T140101.rtf
14 11610 1155 91% 15/08/2010 21:29 T140202.rtf
15 11609 1156 91% 09/08/2010 23:27 T14030101.rtf
7. 7
ACKNOWLEDGEMENTS
SAS® and all other SAS Institute Inc. product or service names are registered trademarks or
trademarks of SAS Institute Inc. in the USA and other countries. ® indicates USA registration.
The authors would like to thank Jim Worley and Kipp Spanbauer for their comments in their
careful review of the paper.
CONTACT INFORMATION
Your comments and questions are valued and encouraged.
Contact the authors at:
Kenneth W. Borowiak Michael Kwee
PPD, Inc. PPD, Inc.
3900 Paramount Parkway 3900 Paramount Parkway
Morrisville, NC 27560 Morrisville, NC 27560
ken.borowiak@ppdi.com michael.kwee@ppdi.com
REFERENCES
Borowiak, Kenneth (2008), “PRX Functions and Call Routines: There is Hardly Anything Regular
About Them”, Proceedings of the 21st
Annual NorthEast SAS Users Group
Brennan, David (2006), “A Quick Guide to the WinZip® Command Line Add-On”, PhUSE
Proceedings
Sample 26011: Reading zipped files on Windows - http://support.sas.com/kb/26/011.html
WinZip Command Line Support Add-On Release 1.0
APPENDIX
libname NESUG "C:NESUG" ;
data nesug.ae nesug.cm nesug.dm nesug.ds nesug.mh nesug.vs ;
set sashelp.class ;
run ;
x 'cd C:NESUG' ;
%macro sample_table(dsn= , tableno=, where= ) ;
ods rtf file="&tableno..rtf" style=minimal ;
proc print data=&dsn. label ;
%if %length(&where.)>0 %then where &where.;;
run ;
ods rtf close ;
%mend ;
%sample_table(dsn=nesug.ae, tableno=T140101)
%sample_table(dsn=nesug.ae, tableno=T140202)
%sample_table(dsn=nesug.ae, tableno=T14030101, where=%str(sex='F'))
%sample_table(dsn=nesug.ae, tableno=T14030102, where=%str(sex='M'))