BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Billybob73
Quartz | Level 8

Hi,

I have the code below (partial code)  to extract files from zipfiles. As you can see I only keep the zipfile name and the contents of the zipfile. However I would like to have file properties of the individual zip file files such as Last Update, Date Creation, Author, File Size.

 

What would I add to the code below to achieve that ?

 

Many thanks !

 

 

%do i = 1 %to &zipcount;
    filename targzip ZIP "%bquote(%superq(targdir)/%superq(zname&i))";
     data _contents&i.(keep=zip memname);
      length zip $200 memname $200;
   zip="%bquote(%superq(targdir)/%superq(zname&i))";
      fid=dopen("targzip");
       if fid=0 then
        stop;
      memcount=dnum(fid);
       do i=1 to memcount;
        memname=dread(fid,i);
        if (first(reverse(trim(memname))) ^='/') then
          output;
      end;
       rc=dclose(fid);
    run;
     filename targzip clear;
  %end;

1 ACCEPTED SOLUTION

Accepted Solutions
ChrisHemedinger
Community Manager

The FINFO support was added in SAS 9.4 Maint 3.  Run:

 

proc product_status; run;

To make sure you're at that level or higher.

 

Sample output:

 

For Base SAS Software ...
   Custom version information: 9.4_M5
   Image version information: 9.04.01M5P090617
For SAS/STAT ...
   Custom version information: 14.3
For SAS/GRAPH ...
   Custom version information: 9.4_M5
It's time to register for SAS Innovate! Join your SAS user peers in Las Vegas on April 16-19 2024.

View solution in original post

11 REPLIES 11
RW9
Diamond | Level 26 RW9
Diamond | Level 26

What you are asking for is system information, i.e. from the command line.  This information really isn't useful in any real way, dates and such like can be easily incorrect or manipulated.  What is it your actually trying to do, as it seems to be circling one main issue.  What I suspect is you have a load of ZIP files and you are trying to process them all and document the process.  If you don't need the contents, what is it you actually need?  

As for your question, two options, extract all to folder, then do a dir list of that folder to get those properties.  Or get a tool like 7Zip and call that from the command line to return items from the zip:

https://sevenzip.osdn.jp/chm/cmdline/commands/list.htm

 

Until I know what it is your doing its hard to provide any kind of useful solution.

s_lassen
Meteorite | Level 14

I think you can use the MOPEN and then the FINFO function to get available data about each member, e.g.:

memname=dread(fid,i);
if first(reverse(trim(memname)))^='/' then do;
  mid=mopen(fid,memname);
  Create_time=finfo(mid,'Create Time');
  output;
rc=fclose(mid); end;

See the documentation, and the examples there, for information about which information items are available. The "Author" is not available here, nor is it otherwise available for all file types under the Windows platform, I think this property is saved inside the file for e.g. Office files.

Billybob73
Quartz | Level 8

Hi,

This sounds logical. For some reason i still can't get the syntax right. What is wrong below ?

 

filename targzip ZIP "%bquote(%superq(targdir)/%superq(zname&i))";
 data _contents&i.(keep=zip memname create_time);
length zip $200 memname $200;
 zip="%bquote(%superq(targdir)/%superq(zname&i))";
fid=dopen("targzip");
if fid=0 then
stop;
memcount=dnum(fid);
 do i=1 to memcount;
memname=dread(fid,i);
if (first(reverse(trim(memname))) ^='/') then do;
mid=mopen(fid,memname);
Create_time=finfo(mid,'Create Time');
output;
rc=fclose(mid);
end;
rc=dclose(fid);
end;
run;
filename targzip clear;

 

Thanks !

Rgds

B

 

 

ChrisHemedinger
Community Manager

I have an example of how to accomplish this here:

 

 Using FILENAME ZIP and FINFO to list details from your ZIP files

 

A complete SAS macro that you can use is in my GitHub gist.

It's time to register for SAS Innovate! Join your SAS user peers in Las Vegas on April 16-19 2024.
Billybob73
Quartz | Level 8

Hi Chris,

Thanks very much for the link. I would like to see the example.

I clicked on it but unfortunately it does not work.

Rgds

B

Billybob73
Quartz | Level 8

Hi Chris,

Sorry for my previous message and the confusieon. The link does work. However my company's security policy prevents me from downloading your code.

Just was able to open it on my mobile 😉

Thanks for your explanation on this supported with code !

Rgds

B

Reeza
Super User

A company blocking GitHub seems like a really bad decision, especially for developers.

 

Here's a copy of Chris's code.

 

/* Produce a list of ZIP files and their entries from a single folder */
%macro listzipcontents (
     targdir= /* a system folder that contains ZIP files       */, 
     outlist= /* output data set for list of files and members */);
  filename targdir "&targdir";
 
  /* Gather all ZIP files in a given folder                */
  /* Searches just one folder, not subfolders              */
  /* for a fancier example see                             */
  /* http://support.sas.com/kb/45/805.html (Full Code tab) */
  data _zipfiles;
    length fid 8;
    fid=dopen('targdir');
 
    if fid=0 then
      stop;
    memcount=dnum(fid);
 
    /* Find all ZIP files.  GZ files added in 9.4 Maint 5 */
    do i=1 to memcount;
      memname=dread(fid,i);
      if lowcase( scan( memname,-1,'.') in ('zip')) then
        output;
    end;
 
    rc=dclose(fid);
  run;
 
  filename targdir clear;
 
  /* get the memnames into macro vars */ 
  proc sql noprint;
    select memname into: zname1- from _zipfiles;
    %let zipcount=&sqlobs;
  quit;
 
  /* for all ZIP files, gather the members */
  %do i = 1 %to &zipcount;
    %put &targdir/&&zname&i;
    filename targzip ZIP "&targdir/&&zname&i";
 
    data _contents&i.(keep=zip memname);
      length zip $200 memname $200 ;
      zip="&targdir/&&zname&i";
      fid=dopen("targzip");
 
      if fid=0 then
        stop;
      memcount=dnum(fid);
 
      do i=1 to memcount;
        memname=dread(fid,i);
 
        /* save only full file names, not directory names */
        if (first(reverse(trim(memname))) ^='/') then
          output;
      end;
 
      rc=dclose(fid);
    run;
 
    filename targzip clear;
  %end;
 
  /* Combine the member names into a single data set        */
  /* the colon notation matches all files with "_contents" prefix */
  data &outlist.;
    set _contents:;
  run;
 
  /* cleanup temp files */
  proc datasets lib=work nodetails nolist;
    delete _contents:;
    delete _zipfiles;
  run;
 
%mend;

/* Build the file details for a single ZIP member */
%macro getzipmemberinfo(
  f /* fileref of a ZIP/member= combination */,
  out /* output data set for details of just this ZIP member */);
  data &out.;
  length filename $ 200
         membername $ 200
		 filetime 8
		 filesize 8
		 compressedsize 8
		 compressedratio 8
		 CRC32 $ 8;
    keep filename 
         membername 
		 filetime 
		 filesize 
		 compressedsize 
		 compressedratio
		 CRC32;
	format filetime datetime20.
	       filesize sizekmg10.2
		   compressedsize sizekmg10.2
           compressedratio percent6.;

    /* These FINFO attributes are specific to ZIP file members */
    fId = fopen("&f","S");
    if fID then
	    do;
	     infonum=foptnum(fid);
		     do i=1 to infonum;
		      infoname=foptname(fid,i);
			  select (infoname);
			   when ('Filename') filename=finfo(fid,infoname);
			   when ('Member Name') membername=finfo(fid,infoname);
			   when ('Size') filesize=input(finfo(fid,infoname),15.);
			   when ('Compressed Size') compressedsize=input(finfo(fid,infoname),15.);
			   when ('CRC-32') crc32=finfo(fid,infoname);
			   when ('Date/Time') filetime=input(finfo(fid,infoname),anydtdtm.);
			  end;    
	     end;
	 compressedratio = compressedsize / filesize;
	 output;
     fId = fClose( fId );
   end;
  run;
%mend;

/* Given a data set of ZIP file names and entries, assemble the member details */
/* Assumes input contains 'zip' and 'memname' columns, as produced by          */
/* the %listzipcontents() macro.                                               */
%macro getZipDetails(
   inlist= /* two-column data set with zip (full path of ZIP file) and memname (entry in ZIP file) */,
   outlist= /* data set for output details */);

    /* Build a list of FILENAME statements */
	proc sql noprint;
	 select cat('FILENAME f ZIP "',trim(zip),'" member="',trim(memname),'";') length=300 
	   into: fnames1-  from &inlist.;
	 %let fcount=&sqlobs.;
	quit;

  /* One by one, assign the fileref to a ZIP member, fetch details, clear fileref */
  %do i = 1 %to &fcount;
    &&fnames&i.;
	%getzipmemberinfo(f,_deets&i.);
	filename f clear;
  %end;

  /* aggegate results into a single output */
  data &outlist.;
   set _deets:;
  run;

  /* Clean up temp files */
  proc datasets lib=work nodetails nolist;
  delete _deets:;
  quit;
%mend;

/* To use: first run LISTZIPCONTENTS with folder that contains    */
/* ZIP files you want details for, then run GETZIPDETAILS on the  */
/* output of that. */
/* Output: a SAS data set with zip member details.                */
/*

filename                                     membername                                                           filetime      filesize    compressedsize    compressedratio    CRC32

SAS.MacroViewer.zip                          SAS.MacroViewer.dll                                        29SEP2012:09:49:18      139.00KB         51.32KB            37%          054AEBC6
SASPress.CustomTasks.DS2Datalines_src.zip    src/Properties/AssemblyInfo.cs                             27NOV2012:20:57:06        1.11KB          0.51KB            46%          FAC88DED
SASPress.Facebook_src.zip                    src/FacebookConnector/Properties/AssemblyInfo.cs           16JAN2011:12:06:24        1.43KB          0.63KB            44%          2C86F829
SASPress.Facebook_src.zip                    src/FacebookConnector/Properties/Resources.Designer.cs     21JAN2011:20:04:54        2.78KB          0.90KB            32%          C7508420
SASPress.Facebook_src.zip                    src/FacebookConnector/Properties/Resources.resx            21JAN2011:20:04:54        5.82KB          1.48KB            25%          E0C8C87E
SASPress.Facebook_src.zip                    src/FacebookConnector/Properties/Settings.Designer.cs      19JAN2011:08:28:06        1.07KB          0.45KB            42%          4DDC113E
SASPress.Facebook_src.zip                    src/FacebookConnector/Properties/Settings.settings         16JAN2011:12:06:24        0.24KB          0.17KB            70%          12D89760
SASPress.Facebook_src.zip                    src/FacebookConnector/README.txt                           23JAN2011:13:12:38        5.12KB          2.08KB            41%          19CEF39C
SASPress.Facebook_src.zip                    src/README.txt                                             23JAN2011:13:12:38        5.12KB          2.08KB            41%          19CEF39C

*/

/* Sample use:

  %listzipcontents (targdir=C:\Projects\ZIPPED_Examples, outlist=work.zipfiles);
  %getZipDetails (inlist=work.zipfiles, outlist=work.zipdetails);

*/
Billybob73
Quartz | Level 8

Thanks Reeza !

 

I'm running this but unfortunately i do not get the file properties. I do get the properties :

filenamemembernamefiletimefilesizecompressedsizecompressedratioCRC32
g:\folder1\folder2\test1.zipTESTFILE1.TXT.....
g:\folder1\folder2\test2.zipTESFILE2.TXT.....

This is my macro call :


%listzipcontents (targdir=g:\folder1\folder2\20171230, outlist=work.zipfiles);

%getZipDetails (inlist=work.zipfiles, outlist=work.zipdetails);

What could go wrong ?

I copied the exact contents of the macros...

 

Thanks

B

Billybob73
Quartz | Level 8

Sorry I meant :

 

%listzipcontents (targdir=g:\folder1\folder2, outlist=work.zipfiles);

%getZipDetails (inlist=work.zipfiles, outlist=work.zipdetails);

ChrisHemedinger
Community Manager

The FINFO support was added in SAS 9.4 Maint 3.  Run:

 

proc product_status; run;

To make sure you're at that level or higher.

 

Sample output:

 

For Base SAS Software ...
   Custom version information: 9.4_M5
   Image version information: 9.04.01M5P090617
For SAS/STAT ...
   Custom version information: 14.3
For SAS/GRAPH ...
   Custom version information: 9.4_M5
It's time to register for SAS Innovate! Join your SAS user peers in Las Vegas on April 16-19 2024.
Billybob73
Quartz | Level 8

 

Hi Chris,

 

Thanks for sharing this.

 

It appears we have M1.

 

For Base SAS Software ...

Custom version information: 9.4_M1

Image version information: 9.04.01M1P120413

 

It's a huge relief. For a moment I really thought I would go crazy 😉

 

Is there another way to get file details from files within zip files ?

 

Thanks again !

Rgds

B

 

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 11 replies
  • 1463 views
  • 2 likes
  • 5 in conversation