BookmarkSubscribeRSS Feed
Walternate
Obsidian | Level 7

Hi all,

 

I have a list of data files, each one is in a directory:

 

dir                               file

dira                             file1

dira/dirb                    file2  

dira/dirc/                   file3

 

I am trying to move the files to a new location which is calculated based on the value of dir. 

 

The problem is, the new locations need to be built programatically and there are too many to do manually. 

 

I tried using dlcreatedir to buidl libname statements, but this is causing errors in cases when a folder has data files but the parent folder does not. 

 

This is what I have:

proc sql noprint;
select count(directory) into :num_dirs 
from xl_file_srt;
quit;
 
%macro buildem;
 
 
%do i= 1 %to &num_dirs.;
 
data _null_;
set xl_file_srt;
 
call symputx('lib'||strip(_n_), new_loc);
 
run;
%let lib = &&lib&i..;
 
libname d1 "&lib.";
 
/* %let i = %eval(&i.+1);*/
%end;
 
%mend buildem;
%buildem;
 
The only other setup other than the dlcreatedir option is that I had sorted by number of nodes/slashes . 

 

Any help is much appreciated. 

2 REPLIES 2
ballardw
Super User

Probably you problem with DLCREATEDIR is described here:

Restriction If the path specified in the LIBNAME statement contains multiple components, SAS creates only the final component in the path. If any intermediate components of the path do not exist, SAS does not assign the specified path.

 

That means you can add ONE level to an EXISTING directory. It is quite likely that the order of your current statements is violating that. I say likely because we do not have 1) your current directory structure 2) the data set you are using to get the names 3) the code generated or 4) the actual error messages. You code would have to make sure one directory existed before making the subdirectories and there might be some system lag depending on where you are creating them.

 

I also don't see anything in the code shown that I can identify as a drive letter, disk mount point or network share as the start of a valid path.

 

If you have a lot of stuff like this I would personally use use SAS to generate MKDIR or MAKEDIR statements, write them to a batch file and execute the system command statements.

 

FWIW, there is also a LIBNAME function available in data step code to create or clear libraries using data step variables. Might be easier than that macro to debug.

 

Tom
Super User Tom
Super User

Just loop over the number of levels in each directory.


%let dlcreatedir=%sysfunc(getoption(dlcreatedir));
options dlcreatedir ;

data want ;
  set xl_file_srt ;
  length libname $8 path $256 ;
  libname=cats('LIB',_n_);
  do level=1 to countw(directory,'/');
    path=catx('/',path,scan(directory,level,'/'));
    rc=libname(libname,path);
  end;
run;
options &dlcreatedir;

If you don't want to actually assign the librefs you could just use the same value of LIBNAME for each observation instead.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 2 replies
  • 365 views
  • 0 likes
  • 3 in conversation