Hi All,
I need to put all SAS program names in one file and in one line. I already have list of program names in a file. I need to create a simple txt file and put program names like this
abc.sas xyz.sas abc2.sas etc.
How can you achieve this with put and infile statement ?
Then try this:
%dirtree(/space/kstr395/brim/misc/programs)
data _null_;
set dirtree;
if index(filename,'.') and lowcase(scan(filename,-1,'.'))='sas';
file "/space/kstr395/brim/misc/programs/batch.txt" recfm=n ;
put filename;
run;
How is the file you already have structured? Can you show an example?
This question shows how to create a text file from a SAS data set as a single line.
data _null_;
file "test.txt" recfm=N dlm=' ' lrecl=500000;
set have;
put (_all_)(:) +(-1) @;
run;
@Leo9 wrote:
Hi All,
I need to put all SAS program names in one file and in one line. I already have list of program names in a file. I need to create a simple txt file and put program names like this
abc.sas xyz.sas abc2.sas etc.
How can you achieve this with put and infile statement ?
Thank you. In your example there has to be a text file already created to put the program names. I want to create a txt file within the program itself (without manually creating it) and then use that text file to put the program names.
@Leo9 wrote:
Thank you. In your example there has to be a text file already created to put the program names. I want to create a txt file within the program itself (without manually creating it) and then use that text file to put the program names.
Your description is backwards.
You cannot use a text file to put names. You use SAS code to put the names into the text file.
The program shown was creating a text file. It assumed you had the list of filenames in a dataset.
So let's assume you have dataset named PROGRAMS which has a variable named FILENAME and you want to create a file named 'program_names.txt'. Then this program will write one line to the file with a space between each filename.
data _null_;
file 'program_names.txt';
set programs;
put filename @ ;
run;
If the filenames might have spaces in them then perhaps you want to add the DSD and DLM option to the file statement. That way SAS will quote the names of any files that have spaces in them. Otherwise the list would be confusing.
data _null_;
file 'program_names.txt' dsd dlm=' ';
set programs;
put filename @ ;
run;
@Leo9 wrote:
Thank you. In your example there has to be a text file already created to put the program names. I want to create a txt file within the program itself (without manually creating it) and then use that text file to put the program names.
No, there needs to be a SAS data set with the program names.
Where are the program names? Do you need to look through a folder and file all files? Or something else.
Please explain what this means from your original post:
I already have list of program names in a file
From where do you get the program names? A dataset, another text file, a directory, or a whole directory tree? Or several directory trees?
Hi All,
Thank you for your responses. I should have been more clearer in my original post. Basically, I am reading names of all the sas programs from a given directory and then I am trying to put them in a text file.
- First read all program names
- Put all these program names in a text file
Here is the full code
filename mybatch "/space/kstr395/brim/misc/programs/batch.txt";
%macro list_files(dir,ext);
%local filrf rc did memcnt name i;
%let rc=%sysfunc(filename(filrf,&dir));
%let did=%sysfunc(dopen(&filrf));
%if &did eq 0 %then %do;
%put Directory &dir cannot be open or does not exist;
%return;
%end;
data _null_ ;
file "/space/kstr395/brim/misc/programs/batch.txt" recfm=N dlm=' ' lrecl=500000;
%do i = 1 %to %sysfunc(dnum(&did));
%let name=%qsysfunc(dread(&did,&i));
%if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;
%put &dir/&name @@;
put &name @@ ;
%end;
%else %if %qscan(&name,2,.) = %then %do;
%list_files(&dir/&name,&ext)
%end;
%end;
run;
%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(filrf));
%mend list_files;
%list_files( %str(/space/kstr395/brim/misc/programs),sas) ;
I am getting an error "Data Step Component Object Failure. Aborted during compilation phase"
Why do you have all of that macro code in there? You are already running a data step so just call the functions directly.
%macro list_files(dir,ext,file);
data _null_;
length filrf $8 ;
rc=filename(filrf,"&dir");
did=dopen(filrf);
if did=0 then do;
putlog "ERROR: Directory &dir cannot be open or does not exist";
stop;
end;
file &file recfm=N ;
do i=1 to dnum(did);
length name $256;
name=dread(did,i);
if index(name,'.') and lowcase(scan(name,-1,'.'))=lowcase("&ext") then do;
put name ;
end;
end;
rc = dclose(did);
rc = filename(filrf);
run;
%mend list_files;
filename mybatch "/space/kstr395/brim/misc/programs/batch.txt";
%list_files(dir=/space/kstr395/brim/misc/programs,ext=sas,file=mybatch)
If you remove all the DATA step code, does the macro work? i.e. as a recursive directory crawler that %PUTs to the log a list of the .sas files found, does that work? I would start by getting that to work, before trying to adapt it to save results in a file.
If you want to traverse a whole subdirectory tree then use something like this.
https://github.com/sasutils/macros/blob/master/dirtree.sas
But then you have to decide how you want to write the names into the file.
Do you want to ignore the directory name?
program1.sas program2.sas program1.sas program2.sas
Do you want to write the subdirectory name also?
program1.sas program2.sas subdir/program1.sas subdir/program2.sas
Does that include the top level directory name also?
/top/program1.sas /top/program2.sas /top/subdir/program1.sas /top/subdir/program2.sas
Thank you for your response. I just want program name like
program1.sas program2.sas program1.sas program2.sas
Then try this:
%dirtree(/space/kstr395/brim/misc/programs)
data _null_;
set dirtree;
if index(filename,'.') and lowcase(scan(filename,-1,'.'))='sas';
file "/space/kstr395/brim/misc/programs/batch.txt" recfm=n ;
put filename;
run;
Thank you! This solution works too. The macro is really great.
Thank you so much, this works.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.