Macros for SAS Application Developers
https://github.com/sasjs/core
mp_unzip.sas
Go to the documentation of this file.
1 /**
2  @file mp_unzip.sas
3  @brief Unzips a zip file
4  @details Opens the zip file and copies all the contents to another directory.
5  It is not possible to retain permissions / timestamps, also the BOF marker
6  is lost so it cannot extract binary files.
7 
8  Usage:
9 
10  filename mc url
11  "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
12  %inc mc;
13 
14  %mp_unzip(ziploc="/some/file.zip",outdir=/some/folder)
15 
16  More info:
17  https://blogs.sas.com/content/sasdummy/2015/05/11/using-filename-zip-to-unzip-and-read-data-files-in-sas/
18 
19  @param [in] ziploc= Fileref or quoted full path, eg: "/path/to/file.zip"
20  @param [out] outdir= (%sysfunc(pathname(work))) Directory in which to write
21  the outputs (created if needed)
22 
23  <h4> SAS Macros </h4>
24  @li mf_mkdir.sas
25  @li mf_getuniquefileref.sas
26  @li mp_binarycopy.sas
27 
28  @version 9.4
29  @author Allan Bowe
30  @source https://github.com/sasjs/core
31 
32 **/
33 
34 %macro mp_unzip(
35  ziploc=
36  ,outdir=%sysfunc(pathname(work))
37 )/*/STORE SOURCE*/;
38 
39 %local f1 f2 ;
40 %let f1=%mf_getuniquefileref();
41 %let f2=%mf_getuniquefileref();
42 
43 /* Macro variable &datazip would be read from the file */
44 filename &f1 ZIP &ziploc;
45 
46 /* create target folder */
47 %mf_mkdir(&outdir)
48 
49 /* Read the "members" (files) from the ZIP file */
50 data _data_(keep=memname isFolder);
51  length memname $200 isFolder 8;
52  fid=dopen("&f1");
53  if fid=0 then stop;
54  memcount=dnum(fid);
55  do i=1 to memcount;
56  memname=dread(fid,i);
57  /* check for trailing / in folder name */
58  isFolder = (first(reverse(trim(memname)))='/');
59  output;
60  end;
61  rc=dclose(fid);
62 run;
63 
64 filename &f2 temp;
65 
66 /* loop through each entry and either create the subfolder or extract member */
67 data _null_;
68  set &syslast;
69  file &f2;
70  if isFolder then call execute('%mf_mkdir(&outdir/'!!memname!!')');
71  else do;
72  qname=quote(cats("&outdir/",memname));
73  bname=cats('(',memname,')');
74  put '/* hat tip: "data _null_" on SAS-L */';
75  put 'data _null_;';
76  put ' infile &f1 ' bname ' lrecl=256 recfm=F length=length eof=eof unbuf;';
77  put ' file ' qname ' lrecl=256 recfm=N;';
78  put ' input;';
79  put ' put _infile_ $varying256. length;';
80  put ' return;';
81  put 'eof:';
82  put ' stop;';
83  put 'run;';
84  end;
85 run;
86 
87 %inc &f2/source2;
88 
89 filename &f2 clear;
90 
91 %mend mp_unzip;