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

I used SAS OnDemand for Academics this semester in my teaching.  I created a lot of examples and put them in named directories, but I just learned that I can't download my work except for one file at a time.  Given the system I can't use pipes.

Is it possible within SAS studio to put an entire folder and its subfolder into a zip file preserving the directory structure using SAS.  I can figure out how to zip one file but can't figure this out.

 

1 ACCEPTED SOLUTION
6 REPLIES 6
ballardw
Super User

What type of files are we discussing? Program files? Data sets? ODS Documents? All of these?

LauraRK
Quartz | Level 8

Ideal: everything. SAS code, data and created output  zipped like it would be if you could just zip it.  The files are not large, they are just organized, and students organize their work because I teach them to organize their work, so it would be nice to be able to download and preserve directory structure somehow. SAS On Demand is a cloud version of SAS Studio, file system is Linux as far as I can tell.

 

Next:  SAS code and data files

Third:  At least SAS code  (I would take this as I have SAS locally so I could always just regenerate things but this is not ideal for students, although students who go on and use SAS in other platforms would at least have their code)

 

The real problem I am trying to solve is that if you work on SAS OnDemand there is no functionality to download more than one file at a time, so I thought one way to archive files would be to zip all the files into a zip file, then you could download the zip file. 

LauraRK
Quartz | Level 8
For some reason when I click on this solution I can't see the post, can others see it? I get permission denied.
Tom
Super User Tom
Super User

They must have moved the post or changed the way the links work.

 

Get the list of files into a dataset.  Use the dataset to generate FCOPY() function calls to copy the files.

 

Here is an example using the %DIRTREE() macro to get the list of files.

So first make sure you have the macro defined.

filename dirtree url "https://raw.githubusercontent.com/sasutils/macros/master/dirtree.sas";
%include dirtree;

Then setup macro variables to point to the source directory and the target file.

%let inpath=c:\project\template ;
%let outfile=c:\project\template.zip ;

Now you can use the %DIRTREE() macro to get the list and then use a data step to generate an input and output fileref and call the FCOPY() function to copy them.   I like to use RECFM=F and LRECL=512 to copy files as BINARY.  I am not sure how to create empty folders, so just ignore the records in the output of %DIRTREE() that are for directories.

%dirtree(&inpath)

data _null_;
   if eof then put 'NOTE: copied ' ncopied 'files from ' "'&inpath'" ' to ' "'&outfile'.";
   set dirtree end=eof;
   where type ne 'D' ;
   length in out $8 target msg $256;
   target=translate(catx('/',substrn(path,length("&inpath")+2),filename),'/','\');
   rc1=filename(in,catx('/',path,filename),'disk','recfm=f lrecl=512');
   rc2=filename(out,"&outfile",'zip',catx(' ','recfm=f lrecl=512',cats('member=',quote(trim(target),"'")))) ;
   rc3=fcopy(in,out);
   if rc3 then do;
     msg=sysmsg();
     put (_n_ rc: target msg) (=);
   end;
   else ncopied+1;
run;

 

LauraRK
Quartz | Level 8

https://stackoverflow.com/questions/41872561/sas-zipping-folder  was a helpful answer.  I pasted the code below so that if the post goes away it will be here.  For SAS OD you need to fix the slashes for the directories.

 

%let n=0;
%macro readCatalog(path, localpath);
    %local rc _path filrf did noe filename fid i;

    %if &localpath = %then
        %let _path=&path;
    %else 
        %let _path=&path\&localpath;

    %let n=%eval(&n+1);
    %let filrf=DIR&n;

    %let rc = %sysfunc(filename(filrf, &_path));
    %let did = %sysfunc(dopen(&filrf));
    %let noe = %sysfunc(dnum(&did));

    %do i = 1 %to &noe;
        %let filename = %bquote(%sysfunc(dread(&did, &i)));
        %let fid = %sysfunc(mopen(&did, &filename));
        %if &fid > 0 %then %do;
            %put &=path &=localpath &=_path &=filename;
            ods package(newzip) add file="&_path\&filename" path="&localpath";
        %end;
        %else %do;
            %if &localpath = %then
                %readCatalog(&path, &filename);
            %else 
                %readCatalog(&path, &localpath\&filename);
        %end;
    %end;
    %let rc=%sysfunc(dclose(&did));
%mend readCatalog;

%macro createZIP(path, archive_name, archive_path);
    %put *** Creating an archive (&archive_path\&archive_name) ***;
    ods package(newzip) open nopf;
    %readCatalog(&path)
    ods package(newzip) publish archive properties(
        archive_name="&archive_name" 
        archive_path="&archive_path"
    );
    ods package(newzip) close;
%mend createZIP;

%createZIP(C:\temp, test.zip, C:\temp2)

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 2249 views
  • 2 likes
  • 3 in conversation